comparison libtomcrypt/src/pk/asn1/der/bit/der_decode_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_decode_bit_string.c
13 ASN.1 DER, encode a BIT STRING, Tom St Denis
14 */
15
16
17 #ifdef LTC_DER
18
19 #define SETBIT(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
20 #define CLRBIT(v, n) (v=((unsigned char)(v) & ~(1U << (unsigned char)(n))))
21
22 /**
23 Store a BIT STRING
24 @param in The DER encoded BIT STRING
25 @param inlen The size of the DER BIT STRING
26 @param out [out] The array of bits stored (8 per char)
27 @param outlen [in/out] The number of bits stored
28 @return CRYPT_OK if successful
29 */
30 int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
31 unsigned char *out, unsigned long *outlen)
32 {
33 unsigned long dlen, blen, x, y;
34
35 LTC_ARGCHK(in != NULL);
36 LTC_ARGCHK(out != NULL);
37 LTC_ARGCHK(outlen != NULL);
38
39 /* packet must be at least 4 bytes */
40 if (inlen < 4) {
41 return CRYPT_INVALID_ARG;
42 }
43
44 /* check for 0x03 */
45 if ((in[0]&0x1F) != 0x03) {
46 return CRYPT_INVALID_PACKET;
47 }
48
49 /* offset in the data */
50 x = 1;
51
52 /* get the length of the data */
53 if (in[x] & 0x80) {
54 /* long format get number of length bytes */
55 y = in[x++] & 0x7F;
56
57 /* invalid if 0 or > 2 */
58 if (y == 0 || y > 2) {
59 return CRYPT_INVALID_PACKET;
60 }
61
62 /* read the data len */
63 dlen = 0;
64 while (y--) {
65 dlen = (dlen << 8) | (unsigned long)in[x++];
66 }
67 } else {
68 /* short format */
69 dlen = in[x++] & 0x7F;
70 }
71
72 /* is the data len too long or too short? */
73 if ((dlen == 0) || (dlen + x > inlen)) {
74 return CRYPT_INVALID_PACKET;
75 }
76
77 /* get padding count */
78 blen = ((dlen - 1) << 3) - (in[x++] & 7);
79
80 /* too many bits? */
81 if (blen > *outlen) {
82 *outlen = blen;
83 return CRYPT_BUFFER_OVERFLOW;
84 }
85
86 /* decode/store the bits */
87 for (y = 0; y < blen; y++) {
88 if (in[x] & (1 << (7 - (y & 7)))) {
89 SETBIT(out[y/8], 7-(y%8));
90 } else {
91 CLRBIT(out[y/8], 7-(y%8));
92 }
93 if ((y & 7) == 7) {
94 ++x;
95 }
96 }
97
98 /* we done */
99 *outlen = blen;
100 return CRYPT_OK;
101 }
102
103 #endif
104
105 /* ref: $Format:%D$ */
106 /* git commit: $Format:%H$ */
107 /* commit time: $Format:%ai$ */