comparison libtomcrypt/src/pk/asn1/der/bit/der_encode_raw_bit_string.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 */
9 #include "tomcrypt.h"
10
11 /**
12 @file der_encode_bit_string.c
13 ASN.1 DER, encode a BIT STRING, Tom St Denis
14 */
15
16
17 #ifdef LTC_DER
18
19 #define getbit(n, k) (((n) & ( 1 << (k) )) >> (k))
20
21 /**
22 Store a BIT STRING
23 @param in The array of bits to store (8 per char)
24 @param inlen The number of bits to store
25 @param out [out] The destination for the DER encoded BIT STRING
26 @param outlen [in/out] The max size and resulting size of the DER BIT STRING
27 @return CRYPT_OK if successful
28 */
29 int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen,
30 unsigned char *out, unsigned long *outlen)
31 {
32 unsigned long len, x, y;
33 unsigned char buf;
34 int err;
35
36 LTC_ARGCHK(in != NULL);
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39
40 /* avoid overflows */
41 if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
42 return err;
43 }
44
45 if (len > *outlen) {
46 *outlen = len;
47 return CRYPT_BUFFER_OVERFLOW;
48 }
49
50 /* store header (include bit padding count in length) */
51 x = 0;
52 y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
53
54 out[x++] = 0x03;
55 if (y < 128) {
56 out[x++] = (unsigned char)y;
57 } else if (y < 256) {
58 out[x++] = 0x81;
59 out[x++] = (unsigned char)y;
60 } else if (y < 65536) {
61 out[x++] = 0x82;
62 out[x++] = (unsigned char)((y>>8)&255);
63 out[x++] = (unsigned char)(y&255);
64 }
65
66 /* store number of zero padding bits */
67 out[x++] = (unsigned char)((8 - inlen) & 7);
68
69 /* store the bits in big endian format */
70 for (y = buf = 0; y < inlen; y++) {
71 buf |= (getbit(in[y/8],7-y%8)?1:0) << (7 - (y & 7));
72 if ((y & 7) == 7) {
73 out[x++] = buf;
74 buf = 0;
75 }
76 }
77 /* store last byte */
78 if (inlen & 7) {
79 out[x++] = buf;
80 }
81
82 *outlen = x;
83 return CRYPT_OK;
84 }
85
86 #endif
87
88 /* ref: $Format:%D$ */
89 /* git commit: $Format:%H$ */
90 /* commit time: $Format:%ai$ */