Mercurial > dropbear
comparison libtomcrypt/src/misc/base64/base64_decode.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 | f849a5ca2efc |
children | d885a77b98e0 |
comparison
equal
deleted
inserted
replaced
1470:8bba51a55704 | 1471:6dba84798cd5 |
---|---|
3 * LibTomCrypt is a library that provides various cryptographic | 3 * LibTomCrypt is a library that provides various cryptographic |
4 * algorithms in a highly modular and flexible manner. | 4 * algorithms in a highly modular and flexible manner. |
5 * | 5 * |
6 * The library is free for all purposes without any express | 6 * The library is free for all purposes without any express |
7 * guarantee it works. | 7 * guarantee it works. |
8 * | |
9 * Tom St Denis, [email protected], http://libtom.org | |
10 */ | 8 */ |
11 #include "tomcrypt.h" | 9 #include "tomcrypt.h" |
12 | 10 |
13 /** | 11 /** |
14 @file base64_decode.c | 12 @file base64_decode.c |
15 Compliant base64 code donated by Wayne Scott ([email protected]) | 13 Compliant base64 code donated by Wayne Scott ([email protected]) |
14 base64 URL Safe variant (RFC 4648 section 5) by Karel Miko | |
16 */ | 15 */ |
17 | 16 |
18 | 17 |
19 #ifdef LTC_BASE64 | 18 #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) |
20 | 19 |
21 static const unsigned char map[256] = { | 20 #if defined(LTC_BASE64) |
21 static const unsigned char map_base64[256] = { | |
22 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 22 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
23 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 23 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
24 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 24 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
25 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, | 25 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, |
26 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, | 26 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, |
39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 39 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 40 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 41 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | 42 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
43 255, 255, 255, 255 }; | 43 255, 255, 255, 255 }; |
44 #endif /* LTC_BASE64 */ | |
44 | 45 |
45 /** | 46 static const unsigned char map_base64url[] = { |
46 base64 decode a block of memory | 47 #if defined(LTC_BASE64_URL) |
47 @param in The base64 data to decode | 48 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
48 @param inlen The length of the base64 data | 49 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
49 @param out [out] The destination of the binary decoded data | 50 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |
50 @param outlen [in/out] The max size and resulting size of the decoded data | 51 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, |
51 @return CRYPT_OK if successful | 52 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, |
52 */ | 53 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, |
53 int base64_decode(const unsigned char *in, unsigned long inlen, | 54 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, |
54 unsigned char *out, unsigned long *outlen) | 55 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, |
56 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, | |
57 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, | |
58 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
60 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
61 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
62 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
63 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
64 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
65 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
66 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
67 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
68 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
69 255, 255, 255, 255 | |
70 #endif /* LTC_BASE64_URL */ | |
71 }; | |
72 | |
73 enum { | |
74 relaxed = 0, | |
75 strict = 1 | |
76 }; | |
77 | |
78 static int _base64_decode_internal(const unsigned char *in, unsigned long inlen, | |
79 unsigned char *out, unsigned long *outlen, | |
80 const unsigned char *map, int is_strict) | |
55 { | 81 { |
56 unsigned long t, x, y, z; | 82 unsigned long t, x, y, z; |
57 unsigned char c; | 83 unsigned char c; |
58 int g; | 84 int g; |
59 | 85 |
60 LTC_ARGCHK(in != NULL); | 86 LTC_ARGCHK(in != NULL); |
61 LTC_ARGCHK(out != NULL); | 87 LTC_ARGCHK(out != NULL); |
62 LTC_ARGCHK(outlen != NULL); | 88 LTC_ARGCHK(outlen != NULL); |
63 | 89 |
64 g = 3; | 90 g = 0; /* '=' counter */ |
65 for (x = y = z = t = 0; x < inlen; x++) { | 91 for (x = y = z = t = 0; x < inlen; x++) { |
66 c = map[in[x]&0xFF]; | 92 c = map[in[x]&0xFF]; |
67 if (c == 255) continue; | 93 if (c == 254) { |
68 /* the final = symbols are read and used to trim the remaining bytes */ | 94 g++; |
69 if (c == 254) { | 95 continue; |
70 c = 0; | 96 } |
71 /* prevent g < 0 which would potentially allow an overflow later */ | 97 else if (is_strict && g > 0) { |
72 if (--g < 0) { | 98 /* we only allow '=' to be at the end */ |
99 return CRYPT_INVALID_PACKET; | |
100 } | |
101 if (c == 255) { | |
102 if (is_strict) | |
73 return CRYPT_INVALID_PACKET; | 103 return CRYPT_INVALID_PACKET; |
74 } | 104 else |
75 } else if (g != 3) { | 105 continue; |
76 /* we only allow = to be at the end */ | |
77 return CRYPT_INVALID_PACKET; | |
78 } | 106 } |
79 | 107 |
80 t = (t<<6)|c; | 108 t = (t<<6)|c; |
81 | 109 |
82 if (++y == 4) { | 110 if (++y == 4) { |
83 if (z + g > *outlen) { | 111 if (z + 3 > *outlen) return CRYPT_BUFFER_OVERFLOW; |
84 return CRYPT_BUFFER_OVERFLOW; | |
85 } | |
86 out[z++] = (unsigned char)((t>>16)&255); | 112 out[z++] = (unsigned char)((t>>16)&255); |
87 if (g > 1) out[z++] = (unsigned char)((t>>8)&255); | 113 out[z++] = (unsigned char)((t>>8)&255); |
88 if (g > 2) out[z++] = (unsigned char)(t&255); | 114 out[z++] = (unsigned char)(t&255); |
89 y = t = 0; | 115 y = t = 0; |
90 } | 116 } |
91 } | 117 } |
118 | |
92 if (y != 0) { | 119 if (y != 0) { |
93 return CRYPT_INVALID_PACKET; | 120 if (y == 1) return CRYPT_INVALID_PACKET; |
121 if ((y + g) != 4 && is_strict && map != map_base64url) return CRYPT_INVALID_PACKET; | |
122 t = t << (6 * (4 - y)); | |
123 if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW; | |
124 if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255); | |
125 if (y == 3) out[z++] = (unsigned char) ((t >> 8) & 255); | |
94 } | 126 } |
95 *outlen = z; | 127 *outlen = z; |
96 return CRYPT_OK; | 128 return CRYPT_OK; |
97 } | 129 } |
98 | 130 |
131 #if defined(LTC_BASE64) | |
132 /** | |
133 Relaxed base64 decode a block of memory | |
134 @param in The base64 data to decode | |
135 @param inlen The length of the base64 data | |
136 @param out [out] The destination of the binary decoded data | |
137 @param outlen [in/out] The max size and resulting size of the decoded data | |
138 @return CRYPT_OK if successful | |
139 */ | |
140 int base64_decode(const unsigned char *in, unsigned long inlen, | |
141 unsigned char *out, unsigned long *outlen) | |
142 { | |
143 return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed); | |
144 } | |
145 | |
146 /** | |
147 Strict base64 decode a block of memory | |
148 @param in The base64 data to decode | |
149 @param inlen The length of the base64 data | |
150 @param out [out] The destination of the binary decoded data | |
151 @param outlen [in/out] The max size and resulting size of the decoded data | |
152 @return CRYPT_OK if successful | |
153 */ | |
154 int base64_strict_decode(const unsigned char *in, unsigned long inlen, | |
155 unsigned char *out, unsigned long *outlen) | |
156 { | |
157 return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict); | |
158 } | |
159 #endif /* LTC_BASE64 */ | |
160 | |
161 #if defined(LTC_BASE64_URL) | |
162 /** | |
163 Relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
164 @param in The base64 data to decode | |
165 @param inlen The length of the base64 data | |
166 @param out [out] The destination of the binary decoded data | |
167 @param outlen [in/out] The max size and resulting size of the decoded data | |
168 @return CRYPT_OK if successful | |
169 */ | |
170 int base64url_decode(const unsigned char *in, unsigned long inlen, | |
171 unsigned char *out, unsigned long *outlen) | |
172 { | |
173 return _base64_decode_internal(in, inlen, out, outlen, map_base64url, relaxed); | |
174 } | |
175 | |
176 /** | |
177 Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
178 @param in The base64 data to decode | |
179 @param inlen The length of the base64 data | |
180 @param out [out] The destination of the binary decoded data | |
181 @param outlen [in/out] The max size and resulting size of the decoded data | |
182 @return CRYPT_OK if successful | |
183 */ | |
184 int base64url_strict_decode(const unsigned char *in, unsigned long inlen, | |
185 unsigned char *out, unsigned long *outlen) | |
186 { | |
187 return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict); | |
188 } | |
189 #endif /* LTC_BASE64_URL */ | |
190 | |
99 #endif | 191 #endif |
100 | 192 |
101 | 193 |
102 /* $Source$ */ | 194 /* ref: $Format:%D$ */ |
103 /* $Revision$ */ | 195 /* git commit: $Format:%H$ */ |
104 /* $Date$ */ | 196 /* commit time: $Format:%ai$ */ |