1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ 2 /* SPDX-License-Identifier: Unlicense */ 3 #include "tomcrypt_private.h" 4 5 /** 6 @file der_encode_asn1_length.c 7 ASN.1 DER, encode the ASN.1 length field, Steffen Jaeckel 8 */ 9 10 #ifdef LTC_DER 11 /** 12 Encode the ASN.1 length field 13 @param len The length to encode 14 @param out Where to write the length field to 15 @param outlen [in/out] The size of out available/written 16 @return CRYPT_OK if successful 17 */ der_encode_asn1_length(unsigned long len,unsigned char * out,unsigned long * outlen)18int der_encode_asn1_length(unsigned long len, unsigned char *out, unsigned long *outlen) 19 { 20 unsigned long x, y; 21 22 LTC_ARGCHK(outlen != NULL); 23 24 x = len; 25 y = 0; 26 27 while(x != 0) { 28 y++; 29 x >>= 8; 30 } 31 if (y == 0) { 32 return CRYPT_PK_ASN1_ERROR; 33 } 34 35 if (out == NULL) { 36 if (len < 128) { 37 x = y; 38 } else { 39 x = y + 1; 40 } 41 } else { 42 if (*outlen < y) { 43 return CRYPT_BUFFER_OVERFLOW; 44 } 45 x = 0; 46 if (len < 128) { 47 out[x++] = (unsigned char)len; 48 } else if (len <= 0xffUL) { 49 out[x++] = 0x81; 50 out[x++] = (unsigned char)len; 51 } else if (len <= 0xffffUL) { 52 out[x++] = 0x82; 53 out[x++] = (unsigned char)((len>>8UL)&255); 54 out[x++] = (unsigned char)(len&255); 55 } else if (len <= 0xffffffUL) { 56 out[x++] = 0x83; 57 out[x++] = (unsigned char)((len>>16UL)&255); 58 out[x++] = (unsigned char)((len>>8UL)&255); 59 out[x++] = (unsigned char)(len&255); 60 #if ULONG_MAX != ULLONG_MAX 61 } else { 62 out[x++] = 0x84; 63 out[x++] = (unsigned char)((len>>24UL)&255); 64 out[x++] = (unsigned char)((len>>16UL)&255); 65 out[x++] = (unsigned char)((len>>8UL)&255); 66 out[x++] = (unsigned char)(len&255); 67 } 68 #else 69 } else if (len <= 0xffffffffUL) { 70 out[x++] = 0x84; 71 out[x++] = (unsigned char)((len>>24UL)&255); 72 out[x++] = (unsigned char)((len>>16UL)&255); 73 out[x++] = (unsigned char)((len>>8UL)&255); 74 out[x++] = (unsigned char)(len&255); 75 } else if (len <= 0xffffffffffULL) { 76 out[x++] = 0x85; 77 out[x++] = (unsigned char)((len>>32ULL)&255); 78 out[x++] = (unsigned char)((len>>24ULL)&255); 79 out[x++] = (unsigned char)((len>>16ULL)&255); 80 out[x++] = (unsigned char)((len>>8ULL)&255); 81 out[x++] = (unsigned char)(len&255); 82 } else if (len <= 0xffffffffffffULL) { 83 out[x++] = 0x86; 84 out[x++] = (unsigned char)((len>>40ULL)&255); 85 out[x++] = (unsigned char)((len>>32ULL)&255); 86 out[x++] = (unsigned char)((len>>24ULL)&255); 87 out[x++] = (unsigned char)((len>>16ULL)&255); 88 out[x++] = (unsigned char)((len>>8ULL)&255); 89 out[x++] = (unsigned char)(len&255); 90 } else if (len <= 0xffffffffffffffULL) { 91 out[x++] = 0x87; 92 out[x++] = (unsigned char)((len>>48ULL)&255); 93 out[x++] = (unsigned char)((len>>40ULL)&255); 94 out[x++] = (unsigned char)((len>>32ULL)&255); 95 out[x++] = (unsigned char)((len>>24ULL)&255); 96 out[x++] = (unsigned char)((len>>16ULL)&255); 97 out[x++] = (unsigned char)((len>>8ULL)&255); 98 out[x++] = (unsigned char)(len&255); 99 } else { 100 out[x++] = 0x88; 101 out[x++] = (unsigned char)((len>>56ULL)&255); 102 out[x++] = (unsigned char)((len>>48ULL)&255); 103 out[x++] = (unsigned char)((len>>40ULL)&255); 104 out[x++] = (unsigned char)((len>>32ULL)&255); 105 out[x++] = (unsigned char)((len>>24ULL)&255); 106 out[x++] = (unsigned char)((len>>16ULL)&255); 107 out[x++] = (unsigned char)((len>>8ULL)&255); 108 out[x++] = (unsigned char)(len&255); 109 } 110 #endif 111 } 112 *outlen = x; 113 114 return CRYPT_OK; 115 } 116 117 #endif 118