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_encode_asn1_length.c
14   ASN.1 DER, encode the ASN.1 length field, Steffen Jaeckel
15 */
16 
17 #ifdef LTC_DER
18 /**
19   Encode the ASN.1 length field
20   @param len      The length to encode
21   @param out      Where to write the length field to
22   @param outlen   [in/out] The size of out available/written
23   @return CRYPT_OK if successful
24 */
der_encode_asn1_length(unsigned long len,unsigned char * out,unsigned long * outlen)25 int der_encode_asn1_length(unsigned long len, unsigned char *out, unsigned long *outlen)
26 {
27    unsigned long x, y;
28 
29    LTC_ARGCHK(outlen != NULL);
30 
31    x = len;
32    y = 0;
33 
34    while(x != 0) {
35       y++;
36       x >>= 8;
37    }
38    if (y == 0) {
39       return CRYPT_PK_ASN1_ERROR;
40    }
41 
42    if (out == NULL) {
43       if (len < 128) {
44          x = y;
45       } else {
46          x = y + 1;
47       }
48    } else {
49       if (*outlen < y) {
50          return CRYPT_BUFFER_OVERFLOW;
51       }
52       x = 0;
53       if (len < 128) {
54          out[x++] = (unsigned char)len;
55       } else if (len <= 0xffUL) {
56          out[x++] = 0x81;
57          out[x++] = (unsigned char)len;
58       } else if (len <= 0xffffUL) {
59          out[x++] = 0x82;
60          out[x++] = (unsigned char)((len>>8UL)&255);
61          out[x++] = (unsigned char)(len&255);
62       } else if (len <= 0xffffffUL) {
63          out[x++] = 0x83;
64          out[x++] = (unsigned char)((len>>16UL)&255);
65          out[x++] = (unsigned char)((len>>8UL)&255);
66          out[x++] = (unsigned char)(len&255);
67       #if ULONG_MAX != ULLONG_MAX
68       } else {
69          out[x++] = 0x84;
70          out[x++] = (unsigned char)((len>>24UL)&255);
71          out[x++] = (unsigned char)((len>>16UL)&255);
72          out[x++] = (unsigned char)((len>>8UL)&255);
73          out[x++] = (unsigned char)(len&255);
74       }
75       #else
76       } else if (len <= 0xffffffffUL) {
77          out[x++] = 0x84;
78          out[x++] = (unsigned char)((len>>24UL)&255);
79          out[x++] = (unsigned char)((len>>16UL)&255);
80          out[x++] = (unsigned char)((len>>8UL)&255);
81          out[x++] = (unsigned char)(len&255);
82       } else if (len <= 0xffffffffffULL) {
83          out[x++] = 0x85;
84          out[x++] = (unsigned char)((len>>32ULL)&255);
85          out[x++] = (unsigned char)((len>>24ULL)&255);
86          out[x++] = (unsigned char)((len>>16ULL)&255);
87          out[x++] = (unsigned char)((len>>8ULL)&255);
88          out[x++] = (unsigned char)(len&255);
89       } else if (len <= 0xffffffffffffULL) {
90          out[x++] = 0x86;
91          out[x++] = (unsigned char)((len>>40ULL)&255);
92          out[x++] = (unsigned char)((len>>32ULL)&255);
93          out[x++] = (unsigned char)((len>>24ULL)&255);
94          out[x++] = (unsigned char)((len>>16ULL)&255);
95          out[x++] = (unsigned char)((len>>8ULL)&255);
96          out[x++] = (unsigned char)(len&255);
97       } else if (len <= 0xffffffffffffffULL) {
98          out[x++] = 0x87;
99          out[x++] = (unsigned char)((len>>48ULL)&255);
100          out[x++] = (unsigned char)((len>>40ULL)&255);
101          out[x++] = (unsigned char)((len>>32ULL)&255);
102          out[x++] = (unsigned char)((len>>24ULL)&255);
103          out[x++] = (unsigned char)((len>>16ULL)&255);
104          out[x++] = (unsigned char)((len>>8ULL)&255);
105          out[x++] = (unsigned char)(len&255);
106       } else {
107          out[x++] = 0x88;
108          out[x++] = (unsigned char)((len>>56ULL)&255);
109          out[x++] = (unsigned char)((len>>48ULL)&255);
110          out[x++] = (unsigned char)((len>>40ULL)&255);
111          out[x++] = (unsigned char)((len>>32ULL)&255);
112          out[x++] = (unsigned char)((len>>24ULL)&255);
113          out[x++] = (unsigned char)((len>>16ULL)&255);
114          out[x++] = (unsigned char)((len>>8ULL)&255);
115          out[x++] = (unsigned char)(len&255);
116       }
117       #endif
118    }
119    *outlen = x;
120 
121    return CRYPT_OK;
122 }
123 
124 #endif
125 
126 /* ref:         $Format:%D$ */
127 /* git commit:  $Format:%H$ */
128 /* commit time: $Format:%ai$ */
129