Upgrade libtomcrypt

This commit is contained in:
2025-10-24 19:33:21 +03:00
parent d770dd8df3
commit acc69bb8ad
157 changed files with 922 additions and 761 deletions

View File

@@ -69,7 +69,7 @@ const struct pem_header_id pem_std_headers[] = {
.pka = LTC_PKA_DSA,
},
};
const unsigned long pem_std_headers_num = sizeof(pem_std_headers)/sizeof(pem_std_headers[0]);
const unsigned long pem_std_headers_num = LTC_ARRAY_SIZE(pem_std_headers);
/* Encrypted PEM files */
const struct str pem_proc_type_encrypted = { SET_CSTR(, "Proc-Type: 4,ENCRYPTED") };
@@ -151,7 +151,7 @@ const struct blockcipher_info pem_dek_infos[] =
{ .name = "SEED-CFB,", .algo = "seed", .keylen = 128 / 8, .mode = cm_cfb, },
{ .name = "SEED-OFB,", .algo = "seed", .keylen = 128 / 8, .mode = cm_ofb, },
};
const unsigned long pem_dek_infos_num = sizeof(pem_dek_infos)/sizeof(pem_dek_infos[0]);
const unsigned long pem_dek_infos_num = LTC_ARRAY_SIZE(pem_dek_infos);
int pem_decrypt(unsigned char *data, unsigned long *datalen,
unsigned char *key, unsigned long keylen,
@@ -201,7 +201,7 @@ int pem_decrypt(unsigned char *data, unsigned long *datalen,
goto error_out;
}
if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.blocklen)) != CRYPT_OK) {
if ((err = padding_depad(data, datalen, padding | s.ctx.cbc.ecb.blocklen)) != CRYPT_OK) {
goto error_out;
}
#else

View File

@@ -16,7 +16,7 @@
extern const struct pem_header_id pem_std_headers[];
extern const unsigned long pem_std_headers_num;
static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_headers *hdr)
static int s_decrypt_pem(unsigned char *asn1_cert, unsigned long *asn1_len, const struct pem_headers *hdr)
{
unsigned char iv[MAXBLOCKSIZE], key[MAXBLOCKSIZE];
unsigned long ivlen, klen;
@@ -38,7 +38,7 @@ static int s_decrypt_pem(unsigned char *pem, unsigned long *l, const struct pem_
return err;
}
err = pem_decrypt(pem, l, key, klen, iv, ivlen, NULL, 0, &hdr->info, LTC_PAD_PKCS7);
err = pem_decrypt(asn1_cert, asn1_len, key, klen, iv, ivlen, NULL, 0, &hdr->info, LTC_PAD_PKCS7);
zeromem(key, sizeof(key));
zeromem(iv, sizeof(iv));
@@ -86,12 +86,12 @@ static const import_fn s_import_x509_fns[LTC_PKA_NUM] = {
#endif
};
static int s_import_x509(unsigned char *pem, unsigned long l, ltc_pka_key *k)
static int s_import_x509(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k)
{
enum ltc_pka_id pka = LTC_PKA_UNDEF;
ltc_asn1_list *d, *spki;
int err;
if ((err = x509_decode_spki(pem, l, &d, &spki)) != CRYPT_OK) {
if ((err = x509_decode_spki(asn1_cert, asn1_len, &d, &spki)) != CRYPT_OK) {
return err;
}
err = s_get_pka(spki, &pka);
@@ -100,23 +100,23 @@ static int s_import_x509(unsigned char *pem, unsigned long l, ltc_pka_key *k)
return err;
}
if (pka < 0
|| pka > sizeof(s_import_x509_fns)/sizeof(s_import_x509_fns[0])
|| pka > LTC_ARRAY_SIZE(s_import_x509_fns)
|| s_import_x509_fns[pka] == NULL) {
return CRYPT_PK_INVALID_TYPE;
}
if ((err = s_import_x509_fns[pka](pem, l, &k->u)) == CRYPT_OK) {
if ((err = s_import_x509_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) {
k->id = pka;
}
return err;
}
static int s_import_pkcs8(unsigned char *pem, unsigned long l, ltc_pka_key *k, const password_ctx *pw_ctx)
static int s_import_pkcs8(unsigned char *asn1_cert, unsigned long asn1_len, ltc_pka_key *k, const password_ctx *pw_ctx)
{
int err;
enum ltc_oid_id pka;
ltc_asn1_list *alg_id, *priv_key;
ltc_asn1_list *p8_asn1 = NULL;
if ((err = pkcs8_decode_flexi(pem, l, pw_ctx, &p8_asn1)) != CRYPT_OK) {
if ((err = pkcs8_decode_flexi(asn1_cert, asn1_len, pw_ctx, &p8_asn1)) != CRYPT_OK) {
goto cleanup;
}
if ((err = pkcs8_get_children(p8_asn1, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
@@ -168,11 +168,11 @@ cleanup:
return err;
}
static int s_extract_pka(unsigned char *pem, unsigned long w, enum ltc_pka_id *pka)
static int s_extract_pka(unsigned char *asn1_cert, unsigned long asn1_len, enum ltc_pka_id *pka)
{
ltc_asn1_list *pub;
int err = CRYPT_ERROR;
if ((err = der_decode_sequence_flexi(pem, &w, &pub)) != CRYPT_OK) {
if ((err = der_decode_sequence_flexi(asn1_cert, &asn1_len, &pub)) != CRYPT_OK) {
return err;
}
err = s_get_pka(pub, pka);
@@ -198,8 +198,8 @@ static const import_fn s_import_openssl_fns[LTC_PKA_NUM] = {
static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx)
{
unsigned char *pem = NULL;
unsigned long w, l, n;
unsigned char *asn1_cert = NULL;
unsigned long w, asn1_len, n;
int err = CRYPT_ERROR;
struct pem_headers hdr = { 0 };
struct password pw = { 0 };
@@ -207,10 +207,10 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c
XMEMSET(k, 0, sizeof(*k));
w = LTC_PEM_READ_BUFSIZE * 2;
retry:
pem = XREALLOC(pem, w);
asn1_cert = XREALLOC(asn1_cert, w);
for (n = 0; n < pem_std_headers_num; ++n) {
hdr.id = &pem_std_headers[n];
err = pem_read(pem, &w, &hdr, g);
err = pem_read(asn1_cert, &w, &hdr, g);
if (err == CRYPT_BUFFER_OVERFLOW) {
goto retry;
} else if (err == CRYPT_OK) {
@@ -223,15 +223,15 @@ retry:
/* id not found */
if (hdr.id == NULL)
goto cleanup;
l = w;
asn1_len = w;
if (hdr.id->flags & pf_pkcs8) {
err = s_import_pkcs8(pem, l, k, pw_ctx);
err = s_import_pkcs8(asn1_cert, asn1_len, k, pw_ctx);
goto cleanup;
} else if (hdr.id->flags == pf_x509) {
err = s_import_x509(pem, l, k);
err = s_import_x509(asn1_cert, asn1_len, k);
goto cleanup;
} else if ((hdr.id->flags & pf_public) && hdr.id->pka == LTC_PKA_UNDEF) {
if ((err = s_extract_pka(pem, w, &pka)) != CRYPT_OK) {
if ((err = s_extract_pka(asn1_cert, asn1_len, &pka)) != CRYPT_OK) {
goto cleanup;
}
} else if (hdr.encrypted) {
@@ -246,7 +246,7 @@ retry:
goto cleanup;
}
if ((err = s_decrypt_pem(pem, &l, &hdr)) != CRYPT_OK) {
if ((err = s_decrypt_pem(asn1_cert, &asn1_len, &hdr)) != CRYPT_OK) {
goto cleanup;
}
pka = hdr.id->pka;
@@ -255,18 +255,18 @@ retry:
}
if (pka < 0
|| pka > sizeof(s_import_openssl_fns)/sizeof(s_import_openssl_fns[0])
|| pka > LTC_ARRAY_SIZE(s_import_openssl_fns)
|| s_import_openssl_fns[pka] == NULL) {
err = CRYPT_PK_INVALID_TYPE;
goto cleanup;
}
if ((err = s_import_openssl_fns[pka](pem, l, &k->u)) == CRYPT_OK) {
if ((err = s_import_openssl_fns[pka](asn1_cert, asn1_len, &k->u)) == CRYPT_OK) {
k->id = pka;
}
cleanup:
password_free(hdr.pw, pw_ctx);
XFREE(pem);
XFREE(asn1_cert);
return err;
}

View File

@@ -62,10 +62,10 @@ static void s_tts(char *buf, unsigned long *buflen)
}
}
static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
static char* s_get_line_i(char *buf, unsigned long *buflen, struct get_char *g, int search_for_start)
{
unsigned long blen = 0;
int c = -1, c_;
unsigned long blen = 0, wr = 0;
int c_;
if (g->unget_buf.p) {
if (*buflen < g->unget_buf.len) {
return NULL;
@@ -75,30 +75,44 @@ static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
RESET_STR(g->unget_buf);
return buf;
}
while(blen < *buflen) {
c_ = c;
c = g->get(g);
if (c == '\n') {
buf[blen] = '\0';
if (g->prev_get == -1) {
return NULL;
}
while(blen < *buflen || search_for_start) {
wr = blen < *buflen ? blen : *buflen - 1;
c_ = g->prev_get;
g->prev_get = g->get(g);
if (g->prev_get == '\n') {
buf[wr] = '\0';
if (c_ == '\r') {
buf[--blen] = '\0';
buf[--wr] = '\0';
}
s_tts(buf, &blen);
*buflen = blen;
s_tts(buf, &wr);
*buflen = wr;
return buf;
}
if (c == -1 || c == '\0') {
buf[blen] = '\0';
s_tts(buf, &blen);
*buflen = blen;
if (g->prev_get == -1 || g->prev_get == '\0') {
buf[wr] = '\0';
s_tts(buf, &wr);
*buflen = wr;
return buf;
}
buf[blen] = c;
buf[wr] = g->prev_get;
blen++;
}
return NULL;
}
LTC_INLINE static char* s_get_first_line(char *buf, unsigned long *buflen, struct get_char *g)
{
return s_get_line_i(buf, buflen, g, 1);
}
LTC_INLINE static char* s_get_line(char *buf, unsigned long *buflen, struct get_char *g)
{
return s_get_line_i(buf, buflen, g, 0);
}
static LTC_INLINE int s_fits_buf(void *dest, unsigned long to_write, void *end)
{
unsigned char *d = dest;
@@ -176,20 +190,29 @@ static int s_pem_decode_headers(struct pem_headers *hdr, struct get_char *g)
return CRYPT_OK;
}
int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_char *g)
int pem_read(void *asn1_cert, unsigned long *asn1_len, struct pem_headers *hdr, struct get_char *g)
{
char buf[LTC_PEM_DECODE_BUFSZ];
char *wpem = pem;
char *end = wpem + *w;
char *wpem = asn1_cert;
char *end = wpem + *asn1_len;
const char pem_start[] = "----";
unsigned long slen, linelen;
int err, hdr_ok = 0;
int would_overflow = 0;
unsigned char empty_lines = 0;
linelen = sizeof(buf);
if (s_get_line(buf, &linelen, g) == NULL) {
return CRYPT_INVALID_PACKET;
}
g->prev_get = 0;
do {
linelen = sizeof(buf);
if (s_get_first_line(buf, &linelen, g) == NULL) {
if (g->prev_get == -1)
return CRYPT_NOP;
else
return CRYPT_INVALID_PACKET;
}
if (linelen < sizeof(pem_start) - 1)
continue;
} while(XMEMCMP(buf, pem_start, sizeof(pem_start) - 1) != 0);
if (hdr->id->start.len != linelen || XMEMCMP(buf, hdr->id->start.p, hdr->id->start.len)) {
s_unget_line(buf, linelen, g);
return CRYPT_UNKNOWN_PEM;
@@ -226,16 +249,16 @@ int pem_read(void *pem, unsigned long *w, struct pem_headers *hdr, struct get_ch
/* NUL termination */
wpem++;
/* prevent a wrap-around */
if (wpem < (char*)pem)
if (wpem < (char*)asn1_cert)
return CRYPT_OVERFLOW;
*w = wpem - (char*)pem;
*asn1_len = wpem - (char*)asn1_cert;
return CRYPT_BUFFER_OVERFLOW;
}
*w = wpem - (char*)pem;
*asn1_len = wpem - (char*)asn1_cert;
*wpem++ = '\0';
if ((err = base64_strict_decode(pem, *w, pem, w)) != CRYPT_OK) {
if ((err = base64_strict_decode(asn1_cert, *asn1_len, asn1_cert, asn1_len)) != CRYPT_OK) {
return err;
}
return CRYPT_OK;

View File

@@ -51,7 +51,7 @@ const struct blockcipher_info ssh_ciphers[] =
{ .name = "twofish256-cbc", .algo = "twofish", .keylen = 256 / 8, .mode = cm_cbc },
{ .name = "twofish256-ctr", .algo = "twofish", .keylen = 256 / 8, .mode = cm_ctr },
};
const unsigned long ssh_ciphers_num = sizeof(ssh_ciphers)/sizeof(ssh_ciphers[0]);
const unsigned long ssh_ciphers_num = LTC_ARRAY_SIZE(ssh_ciphers);
struct kdf_options {
const char *name;
@@ -402,7 +402,7 @@ static int s_decode_key(const unsigned char *in, unsigned long *inlen, ltc_pka_k
remaining -= cur_len;
cur_len = remaining;
for (n = 0; n < sizeof(ssh_pkas)/sizeof(ssh_pkas[0]); ++n) {
for (n = 0; n < LTC_ARRAY_SIZE(ssh_pkas); ++n) {
if (ssh_pkas[n].name.p != NULL) {
if (pkalen != ssh_pkas[n].name.len
|| XMEMCMP(pka, ssh_pkas[n].name.p, ssh_pkas[n].name.len) != 0) continue;
@@ -415,7 +415,7 @@ static int s_decode_key(const unsigned char *in, unsigned long *inlen, ltc_pka_k
}
break;
}
if (n == sizeof(ssh_pkas)/sizeof(ssh_pkas[0])) {
if (n == LTC_ARRAY_SIZE(ssh_pkas)) {
return CRYPT_PK_INVALID_TYPE;
}
@@ -490,7 +490,7 @@ static int s_parse_line(char *line, unsigned long *len, ltc_pka_key *key, char *
rlen = *len;
/* Chop up string into the three authorized_keys_elements */
for (n = 0; n < sizeof(elements)/sizeof(elements[0]) && rlen; ++n) {
for (n = 0; n < LTC_ARRAY_SIZE(elements) && rlen; ++n) {
skip_spaces(&r, &rlen);
elements[n].p = r;
if (n != 2)
@@ -502,7 +502,7 @@ static int s_parse_line(char *line, unsigned long *len, ltc_pka_key *key, char *
r++;
}
for (n = 0; n < sizeof(ssh_pkas)/sizeof(ssh_pkas[0]); ++n) {
for (n = 0; n < LTC_ARRAY_SIZE(ssh_pkas); ++n) {
if (ssh_pkas[n].name.p != NULL) {
if (elements[ake_algo_name].len != ssh_pkas[n].name.len
|| XMEMCMP(elements[ake_algo_name].p, ssh_pkas[n].name.p, ssh_pkas[n].name.len) != 0) continue;
@@ -711,7 +711,7 @@ static const struct pem_header_id pem_openssh[] = {
.flags = pf_public
},
};
static const unsigned long pem_openssh_num = sizeof(pem_openssh)/sizeof(pem_openssh[0]);
static const unsigned long pem_openssh_num = LTC_ARRAY_SIZE(pem_openssh);
static int s_decode_openssh(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_ctx)
{
@@ -819,9 +819,11 @@ int ssh_read_authorized_keys_filehandle(FILE *f, ssh_authorized_key_cb cb, void
LTC_ARGCHK(f != NULL);
LTC_ARGCHK(cb != NULL);
fseek(f, 0, SEEK_END);
if (fseek(f, 0, SEEK_END) == -1)
return CRYPT_ERROR;
tot_data = ftell(f);
rewind(f);
if (fseek(f, 0, SEEK_SET) == -1)
return CRYPT_ERROR;
buf = XMALLOC(tot_data);
if (buf == NULL) {
return CRYPT_MEM;