1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 /**
6 @file der_encode_short_integer.c
7 ASN.1 DER, encode an integer, Tom St Denis
8 */
9
10
11 #ifdef LTC_DER
12
13 /**
14 Store a short integer in the range (0,2^32-1)
15 @param num The integer to encode
16 @param out [out] The destination for the DER encoded integers
17 @param outlen [in/out] The max size and resulting size of the DER encoded integers
18 @return CRYPT_OK if successful
19 */
der_encode_short_integer(unsigned long num,unsigned char * out,unsigned long * outlen)20 int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen)
21 {
22 unsigned long len, x, y, z;
23 int err;
24
25 LTC_ARGCHK(out != NULL);
26 LTC_ARGCHK(outlen != NULL);
27
28 /* force to 32 bits */
29 num &= 0xFFFFFFFFUL;
30
31 /* find out how big this will be */
32 if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) {
33 return err;
34 }
35
36 if (*outlen < len) {
37 *outlen = len;
38 return CRYPT_BUFFER_OVERFLOW;
39 }
40
41 /* get len of output */
42 z = 0;
43 y = num;
44 while (y) {
45 ++z;
46 y >>= 8;
47 }
48
49 /* handle zero */
50 if (z == 0) {
51 z = 1;
52 }
53
54 /* see if msb is set */
55 z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
56
57 /* adjust the number so the msB is non-zero */
58 for (x = 0; (z <= 4) && (x < (4 - z)); x++) {
59 num <<= 8;
60 }
61
62 /* store header */
63 x = 0;
64 out[x++] = 0x02;
65 out[x++] = (unsigned char)z;
66
67 /* if 31st bit is set output a leading zero and decrement count */
68 if (z == 5) {
69 out[x++] = 0;
70 --z;
71 }
72
73 /* store values */
74 for (y = 0; y < z; y++) {
75 out[x++] = (unsigned char)((num >> 24) & 0xFF);
76 num <<= 8;
77 }
78
79 /* we good */
80 *outlen = x;
81
82 return CRYPT_OK;
83 }
84
85 #endif
86