Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tomcrypt/src/misc/base64/base64_decode.c
5972 views
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 base64_decode.c
13
Compliant base64 code donated by Wayne Scott ([email protected])
14
base64 URL Safe variant (RFC 4648 section 5) by Karel Miko
15
*/
16
17
18
#if defined(LTC_BASE64) || defined (LTC_BASE64_URL)
19
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,
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,
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,
27
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
28
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
29
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
30
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
31
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
32
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
33
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
34
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
35
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
36
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
37
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
38
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,
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,
43
255, 255, 255, 255 };
44
#endif /* LTC_BASE64 */
45
46
static const unsigned char map_base64url[] = {
47
#if defined(LTC_BASE64_URL)
48
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
49
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
50
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
51
255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,
52
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
53
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
54
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
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)
81
{
82
unsigned long t, x, y, z;
83
unsigned char c;
84
int g;
85
86
LTC_ARGCHK(in != NULL);
87
LTC_ARGCHK(out != NULL);
88
LTC_ARGCHK(outlen != NULL);
89
90
g = 0; /* '=' counter */
91
for (x = y = z = t = 0; x < inlen; x++) {
92
c = map[in[x]&0xFF];
93
if (c == 254) {
94
g++;
95
continue;
96
}
97
else if (is_strict && 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)
103
return CRYPT_INVALID_PACKET;
104
else
105
continue;
106
}
107
108
t = (t<<6)|c;
109
110
if (++y == 4) {
111
if (z + 3 > *outlen) return CRYPT_BUFFER_OVERFLOW;
112
out[z++] = (unsigned char)((t>>16)&255);
113
out[z++] = (unsigned char)((t>>8)&255);
114
out[z++] = (unsigned char)(t&255);
115
y = t = 0;
116
}
117
}
118
119
if (y != 0) {
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);
126
}
127
*outlen = z;
128
return CRYPT_OK;
129
}
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
191
#endif
192
193