3 * This file is part of the AVR-Crypto-Lib.
4 * Copyright (C) 2006, 2007, 2008 Daniel Otte (daniel.otte@rub.de)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * base64 decoder (RFC3548)
29 #include "base64_dec.h"
34 #define USE_GCC_EXTENSION
38 #ifdef USE_GCC_EXTENSION
41 int ascii2bit6(char a) {
62 static uint8_t ascii2bit6(char a)
69 if (r < 0 || r > 25) {
77 if (r < 0 || r > 25) {
107 uint8_t ascii2bit6(uint8_t a) {
108 if(a>='A' && a<='Z') {
111 if(a>='a' && a<= 'z') {
114 if(a>='0' && a<='9') {
117 if(a=='+' || a=='-') {
120 if(a=='/' || a=='_') {
133 int base64_binlength(char *str, uint8_t strict)
140 if (*str == '\n' || *str == '\r') {
154 if (ascii2bit6(*str) == -1) {
170 return (l + 1) / 4 * 3 - 1;
174 return (l + 2) / 4 * 3 - 2;
181 |543210543210543210543210|
182 |765432107654321076543210|
185 |54321054|32105432|10543210|
186 |76543210|76543210|76543210|
190 int base64dec(void *dest, const char *b64str, uint8_t strict)
196 // cli_putstr_P(PSTR("\r\n DBG: got 0x"));
197 // cli_hexdump(b64str, 1);
198 buffer[idx] = ascii2bit6(*b64str);
199 // cli_putstr_P(PSTR(" --> 0x"));
200 // cli_hexdump(buffer+idx, 1);
202 if (buffer[idx] == 0xFF) {
203 if (*b64str == '=') {
208 /* definitly the end */
210 if (*b64str == '\0') {
212 /* definitly the end */
214 if (*b64str == '\r' || *b64str == '\n' || !(strict)) {
215 b64str++; /* charcters that we simply ignore */
223 return -1; /* this happens if we get a '=' in the stream */
228 ((uint8_t*) dest)[0] = buffer[0] << 2 | buffer[1] >> 4;
229 ((uint8_t*) dest)[1] = buffer[1] << 4 | buffer[2] >> 2;
230 ((uint8_t*) dest)[2] = buffer[2] << 6 | buffer[3];
231 dest = (uint8_t*) dest + 3;
236 /* the final touch */
240 ((uint8_t*) dest)[0] = buffer[0] << 2 | buffer[1] >> 4;
241 ((uint8_t*) dest)[1] = buffer[1] << 4 | buffer[2] >> 2;
245 ((uint8_t*) dest)[0] = buffer[0] << 2 | buffer[1] >> 4;