Skip to content

Commit 822ecef

Browse files
committed
Fix length-related wycheproof testcases
Signed-off-by: Steffen Jaeckel <[email protected]>
1 parent 9744883 commit 822ecef

File tree

5 files changed

+23
-5
lines changed

5 files changed

+23
-5
lines changed

Diff for: src/headers/tomcrypt_pk.h

+8
Original file line numberDiff line numberDiff line change
@@ -691,9 +691,17 @@ enum ltc_der_seq {
691691
LTC_DER_SEQ_RELAXED = LTC_DER_SEQ_ZERO,
692692
LTC_DER_SEQ_STRICT = 0x2u,
693693

694+
/** Bit2 - [0]=Relaxed Length Check
695+
* [1]=Strict Length Check */
696+
LTC_DER_SEQ_LEN_RELAXED = LTC_DER_SEQ_ZERO,
697+
LTC_DER_SEQ_LEN_STRICT = 0x4u,
698+
694699
/** Alternative naming */
695700
LTC_DER_SEQ_SET = LTC_DER_SEQ_UNORDERED,
696701
LTC_DER_SEQ_SEQUENCE = LTC_DER_SEQ_ORDERED,
702+
703+
LTC_DER_SEQ_ALL_STRICT = LTC_DER_SEQ_STRICT | LTC_DER_SEQ_LEN_STRICT,
704+
697705
};
698706

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

Diff for: src/headers/tomcrypt_private.h

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

546546
int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen);
547-
int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen);
547+
int der_decode_asn1_length_ex(const unsigned char *in, unsigned long *inlen, unsigned long *outlen, unsigned int flags);
548+
#define der_decode_asn1_length(i, il, ol) der_decode_asn1_length_ex(i, il, ol, 0)
548549
int der_length_asn1_length(unsigned long len, unsigned long *outlen);
549550

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

Diff for: src/pk/asn1/der/custom_type/der_decode_custom_type.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
4747
int err, seq_err, i, ordered;
4848
ltc_asn1_type type;
4949
ltc_asn1_list ident;
50+
unsigned int f;
5051
unsigned long size, x, y, z, blksize;
5152
unsigned char* in_new = NULL;
5253
void *data;
@@ -63,7 +64,8 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
6364
LTC_ARGCHK(list != NULL);
6465

6566
/* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
66-
if (in[x] != 0x30 && in[x] != 0x31) {
67+
f = flags & ~(LTC_DER_SEQ_ALL_STRICT);
68+
if (((f == LTC_DER_SEQ_SEQUENCE) && (in[x] != 0x30)) || (((f == LTC_DER_SEQ_SET) && (in[x] != 0x31)))) {
6769
return CRYPT_INVALID_PACKET;
6870
}
6971
++x;
@@ -116,7 +118,7 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
116118
} else {
117119

118120
y = inlen - x;
119-
if ((err = der_decode_asn1_length(&in[x], &y, &blksize)) != CRYPT_OK) {
121+
if ((err = der_decode_asn1_length_ex(&in[x], &y, &blksize, flags)) != CRYPT_OK) {
120122
goto LBL_ERR;
121123
}
122124
x += y;

Diff for: src/pk/asn1/der/general/der_decode_asn1_length.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
@param outlen [out] The decoded ASN.1 length
1616
@return CRYPT_OK if successful
1717
*/
18-
int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen)
18+
int der_decode_asn1_length_ex(const unsigned char *in, unsigned long *inlen, unsigned long *outlen, unsigned int flags)
1919
{
2020
unsigned long real_len, decoded_len, offset, i;
2121

@@ -42,10 +42,17 @@ int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsign
4242
if (real_len > (*inlen - 1)) {
4343
return CRYPT_BUFFER_OVERFLOW;
4444
}
45+
flags &= LTC_DER_SEQ_LEN_STRICT;
4546
decoded_len = 0;
4647
offset = 1 + real_len;
4748
for (i = 0; i < real_len; i++) {
4849
decoded_len = (decoded_len << 8) | in[1 + i];
50+
if ((flags == LTC_DER_SEQ_LEN_STRICT) && (decoded_len == 0)) {
51+
return CRYPT_PK_ASN1_ERROR;
52+
}
53+
}
54+
if ((flags == LTC_DER_SEQ_LEN_STRICT) && (real_len == 1) && (decoded_len < 128)) {
55+
return CRYPT_PK_ASN1_ERROR;
4956
}
5057
}
5158

Diff for: src/pk/ecc/ecc_verify_hash.c

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

6464
if (sigformat == LTC_ECCSIG_ANSIX962) {
6565
/* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */
66-
if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT,
66+
if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_ALL_STRICT,
6767
LTC_ASN1_INTEGER, 1UL, r,
6868
LTC_ASN1_INTEGER, 1UL, s,
6969
LTC_ASN1_EOL, 0UL, LTC_NULL)) != CRYPT_OK) { goto error; }

0 commit comments

Comments
 (0)