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)18int 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