1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6   @file der_length_integer.c
7   ASN.1 DER, get length of encoding, Tom St Denis
8 */
9 
10 
11 #ifdef LTC_DER
12 /**
13   Gets length of DER encoding of num
14   @param num    The int to get the size of
15   @param outlen [out] The length of the DER encoding for the given integer
16   @return CRYPT_OK if successful
17 */
der_length_integer(void * num,unsigned long * outlen)18 int der_length_integer(void *num, unsigned long *outlen)
19 {
20    unsigned long z, len;
21    int           leading_zero, err;
22 
23    LTC_ARGCHK(num     != NULL);
24    LTC_ARGCHK(outlen  != NULL);
25 
26    if (mp_cmp_d(num, 0) != LTC_MP_LT) {
27       /* positive */
28 
29       /* we only need a leading zero if the msb of the first byte is one */
30       if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
31          leading_zero = 1;
32       } else {
33          leading_zero = 0;
34       }
35 
36       /* size for bignum */
37       len = leading_zero + mp_unsigned_bin_size(num);
38    } else {
39       /* it's negative */
40       /* find power of 2 that is a multiple of eight and greater than count bits */
41       z = mp_count_bits(num);
42       z = z + (8 - (z & 7));
43       if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
44       len = z >> 3;
45    }
46 
47    if ((err = der_length_asn1_length(len, &z)) != CRYPT_OK) {
48       return err;
49    }
50    *outlen = 1 + z + len;
51 
52    return CRYPT_OK;
53 }
54 
55 #endif
56