1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file der_decode_integer.c
7 ASN.1 DER, decode an integer, Tom St Denis
8 */
9
10
11 #ifdef LTC_DER
12
13 /**
14 Read a mp_int integer
15 @param in The DER encoded data
16 @param inlen Size of DER encoded data
17 @param num The first mp_int to decode
18 @return CRYPT_OK if successful
19 */
der_decode_integer(const unsigned char * in,unsigned long inlen,void * num)20 int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
21 {
22 unsigned long x, y;
23 int err;
24
25 LTC_ARGCHK(num != NULL);
26 LTC_ARGCHK(in != NULL);
27
28 /* min DER INTEGER is 0x02 01 00 == 0 */
29 if (inlen < (1 + 1 + 1)) {
30 return CRYPT_INVALID_PACKET;
31 }
32
33 /* ok expect 0x02 when we AND with 0001 1111 [1F] */
34 x = 0;
35 if ((in[x++] & 0x1F) != 0x02) {
36 return CRYPT_INVALID_PACKET;
37 }
38
39 /* get the length of the data */
40 inlen -= x;
41 if ((err = der_decode_asn1_length(in + x, &inlen, &y)) != CRYPT_OK) {
42 return err;
43 }
44 x += inlen;
45
46 if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
47 return err;
48 }
49
50 /* see if it's negative */
51 if (in[x] & 0x80) {
52 void *tmp;
53 if (mp_init(&tmp) != CRYPT_OK) {
54 return CRYPT_MEM;
55 }
56
57 if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) {
58 mp_clear(tmp);
59 return CRYPT_MEM;
60 }
61 mp_clear(tmp);
62 }
63
64 return CRYPT_OK;
65
66 }
67
68 #endif
69