1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file der_decode_asn1_length.c
7 ASN.1 DER, decode the ASN.1 Length field, Steffen Jaeckel
8 */
9
10 #ifdef LTC_DER
11 /**
12 Decode the ASN.1 Length field
13 @param in Where to read the length field from
14 @param inlen [in/out] The size of in available/read
15 @param outlen [out] The decoded ASN.1 length
16 @return CRYPT_OK if successful
17 */
der_decode_asn1_length(const unsigned char * in,unsigned long * inlen,unsigned long * outlen)18 int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen)
19 {
20 unsigned long real_len, decoded_len, offset, i;
21
22 LTC_ARGCHK(in != NULL);
23 LTC_ARGCHK(inlen != NULL);
24
25 if (*inlen < 1) {
26 return CRYPT_BUFFER_OVERFLOW;
27 }
28
29 real_len = in[0];
30
31 if (real_len < 128) {
32 decoded_len = real_len;
33 offset = 1;
34 } else {
35 real_len &= 0x7F;
36 if (real_len == 0) {
37 return CRYPT_PK_ASN1_ERROR;
38 }
39 if (real_len > sizeof(decoded_len)) {
40 return CRYPT_OVERFLOW;
41 }
42 if (real_len > (*inlen - 1)) {
43 return CRYPT_BUFFER_OVERFLOW;
44 }
45 decoded_len = 0;
46 offset = 1 + real_len;
47 for (i = 0; i < real_len; i++) {
48 decoded_len = (decoded_len << 8) | in[1 + i];
49 }
50 }
51
52 if (outlen != NULL) *outlen = decoded_len;
53 if (decoded_len > (*inlen - offset)) return CRYPT_OVERFLOW;
54 *inlen = offset;
55
56 return CRYPT_OK;
57 }
58
59 #endif
60