Skip to content

Commit fe85bcd

Browse files
committed
fix length-related wycheproof testcases
1 parent 2297c1e commit fe85bcd

File tree

5 files changed

+23
-5
lines changed

5 files changed

+23
-5
lines changed

src/headers/tomcrypt_pk.h

+8
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,17 @@ enum ltc_der_seq {
539539
LTC_DER_SEQ_RELAXED = LTC_DER_SEQ_ZERO,
540540
LTC_DER_SEQ_STRICT = 0x2u,
541541

542+
/** Bit2 - [0]=Relaxed Length Check
543+
* [1]=Strict Length Check */
544+
LTC_DER_SEQ_LEN_RELAXED = LTC_DER_SEQ_ZERO,
545+
LTC_DER_SEQ_LEN_STRICT = 0x4u,
546+
542547
/** Alternative naming */
543548
LTC_DER_SEQ_SET = LTC_DER_SEQ_UNORDERED,
544549
LTC_DER_SEQ_SEQUENCE = LTC_DER_SEQ_ORDERED,
550+
551+
LTC_DER_SEQ_ALL_STRICT = LTC_DER_SEQ_STRICT | LTC_DER_SEQ_LEN_STRICT,
552+
545553
};
546554

547555
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,

src/headers/tomcrypt_private.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, lt
311311
int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen);
312312

313313
int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen);
314-
int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen);
314+
int der_decode_asn1_length_ex(const unsigned char *in, unsigned long *inlen, unsigned long *outlen, unsigned int flags);
315+
#define der_decode_asn1_length(i, il, ol) der_decode_asn1_length_ex(i, il, ol, 0)
315316
int der_length_asn1_length(unsigned long len, unsigned long *outlen);
316317

317318
int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,

src/pk/asn1/der/custom_type/der_decode_custom_type.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
5353
int err, seq_err, i, ordered;
5454
ltc_asn1_type type;
5555
ltc_asn1_list ident;
56+
unsigned int f;
5657
unsigned long size, x, y, z, blksize;
5758
unsigned char* in_new = NULL;
5859
void *data;
@@ -69,7 +70,8 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
6970
LTC_ARGCHK(list != NULL);
7071

7172
/* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
72-
if (in[x] != 0x30 && in[x] != 0x31) {
73+
f = flags & ~(LTC_DER_SEQ_ALL_STRICT);
74+
if (((f == LTC_DER_SEQ_SEQUENCE) && (in[x] != 0x30)) || (((f == LTC_DER_SEQ_SET) && (in[x] != 0x31)))) {
7375
return CRYPT_INVALID_PACKET;
7476
}
7577
++x;
@@ -122,7 +124,7 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
122124
} else {
123125

124126
y = inlen - x;
125-
if ((err = der_decode_asn1_length(&in[x], &y, &blksize)) != CRYPT_OK) {
127+
if ((err = der_decode_asn1_length_ex(&in[x], &y, &blksize, flags)) != CRYPT_OK) {
126128
goto LBL_ERR;
127129
}
128130
x += y;

src/pk/asn1/der/general/der_decode_asn1_length.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
@param outlen [out] The decoded ASN.1 length
2222
@return CRYPT_OK if successful
2323
*/
24-
int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen)
24+
int der_decode_asn1_length_ex(const unsigned char *in, unsigned long *inlen, unsigned long *outlen, unsigned int flags)
2525
{
2626
unsigned long real_len, decoded_len, offset, i;
2727

@@ -48,10 +48,17 @@ int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsign
4848
if (real_len > (*inlen - 1)) {
4949
return CRYPT_BUFFER_OVERFLOW;
5050
}
51+
flags &= LTC_DER_SEQ_LEN_STRICT;
5152
decoded_len = 0;
5253
offset = 1 + real_len;
5354
for (i = 0; i < real_len; i++) {
5455
decoded_len = (decoded_len << 8) | in[1 + i];
56+
if ((flags == LTC_DER_SEQ_LEN_STRICT) && (decoded_len == 0)) {
57+
return CRYPT_PK_ASN1_ERROR;
58+
}
59+
}
60+
if ((flags == LTC_DER_SEQ_LEN_STRICT) && (real_len == 1) && (decoded_len < 128)) {
61+
return CRYPT_PK_ASN1_ERROR;
5562
}
5663
}
5764

src/pk/ecc/ecc_verify_hash.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
6969

7070
if (sigformat == LTC_ECCSIG_ANSIX962) {
7171
/* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */
72-
if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT,
72+
if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_ALL_STRICT,
7373
LTC_ASN1_INTEGER, 1UL, r,
7474
LTC_ASN1_INTEGER, 1UL, s,
7575
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; }

0 commit comments

Comments
 (0)