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