1 /* 2 * base64.h -- Fast Base64 stream decoder 3 * 4 * Copyright (c) 2005-2007, Nick Galbreath. 5 * Copyright (c) 2015-2018, Wojciech Mua. 6 * Copyright (c) 2016-2017, Matthieu Darbois. 7 * Copyright (c) 2013-2022, Alfred Klomp. 8 * Copyright (c) 2022, NLnet Labs. All rights reserved. 9 * 10 * SPDX-License-Identifier: BSD-2-Clause 11 * 12 */ 13 #ifndef BASE64_H 14 #define BASE64_H 15 16 // Modified version of https://github.com/aklomp/base64 17 18 struct base64_state { 19 int eof; 20 int bytes; 21 unsigned char carry; 22 }; 23 24 #include <stdint.h> 25 #define CHAR62 '+' 26 #define CHAR63 '/' 27 #define CHARPAD '=' 28 29 // End-of-file definitions. 30 // Almost end-of-file when waiting for the last '=' character: 31 #define BASE64_AEOF 1 32 // End-of-file when stream end has been reached or invalid input provided: 33 #define BASE64_EOF 2 34 35 // In the lookup table below, note that the value for '=' (character 61) is 36 // 254, not 255. This character is used for in-band signaling of the end of 37 // the datastream, and we will use that later. The characters A-Z, a-z, 0-9 38 // and + / are mapped to their "decoded" values. The other bytes all map to 39 // the value 255, which flags them as "invalid input". 40 41 static const uint8_t 42 base64_table_dec_8bit[] = 43 { 44 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 0..15 45 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 16..31 46 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, // 32..47 47 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, // 48..63 48 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64..79 49 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, // 80..95 50 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96..111 51 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, // 112..127 52 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 128..143 53 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 54 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 55 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 57 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 58 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 59 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 60 }; 61 62 63 #if BYTE_ORDER == LITTLE_ENDIAN 64 65 /* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */ 66 67 static const uint32_t base64_table_dec_32bit_d0[256] = { 68 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 69 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 70 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 71 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 72 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 73 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 74 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 75 0xffffffff, 0x000000f8, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000fc, 76 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4, 77 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0xffffffff, 0xffffffff, 78 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 79 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018, 80 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030, 81 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048, 82 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060, 83 0x00000064, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 84 0xffffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078, 85 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090, 86 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8, 87 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0, 88 0x000000c4, 0x000000c8, 0x000000cc, 0xffffffff, 0xffffffff, 0xffffffff, 89 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 90 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 91 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 92 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 93 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 94 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 95 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 96 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 97 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 98 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 99 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 100 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 101 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 102 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 103 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 104 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 105 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 106 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 107 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 108 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 109 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 110 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 111 }; 112 113 114 static const uint32_t base64_table_dec_32bit_d1[256] = { 115 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 116 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 117 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 118 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 119 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 120 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 121 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 122 0xffffffff, 0x0000e003, 0xffffffff, 0xffffffff, 0xffffffff, 0x0000f003, 123 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003, 124 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0xffffffff, 0xffffffff, 125 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 126 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000, 127 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000, 128 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001, 129 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001, 130 0x00009001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 131 0xffffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001, 132 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002, 133 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002, 134 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003, 135 0x00001003, 0x00002003, 0x00003003, 0xffffffff, 0xffffffff, 0xffffffff, 136 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 137 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 138 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 139 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 140 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 141 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 142 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 143 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 144 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 145 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 146 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 147 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 148 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 149 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 150 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 151 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 152 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 153 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 154 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 155 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 156 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 157 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 158 }; 159 160 161 static const uint32_t base64_table_dec_32bit_d2[256] = { 162 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 163 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 164 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 165 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 166 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 167 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 168 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 169 0xffffffff, 0x00800f00, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c00f00, 170 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00, 171 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0xffffffff, 0xffffffff, 172 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 173 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100, 174 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300, 175 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400, 176 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600, 177 0x00400600, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 178 0xffffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700, 179 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900, 180 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00, 181 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00, 182 0x00400c00, 0x00800c00, 0x00c00c00, 0xffffffff, 0xffffffff, 0xffffffff, 183 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 184 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 185 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 186 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 187 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 188 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 189 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 190 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 191 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 192 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 193 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 194 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 195 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 196 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 197 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 198 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 199 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 200 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 201 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 202 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 203 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 204 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 205 }; 206 207 208 static const uint32_t base64_table_dec_32bit_d3[256] = { 209 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 210 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 211 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 212 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 213 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 214 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 215 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 216 0xffffffff, 0x003e0000, 0xffffffff, 0xffffffff, 0xffffffff, 0x003f0000, 217 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000, 218 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0xffffffff, 0xffffffff, 219 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 220 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, 221 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000, 222 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000, 223 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000, 224 0x00190000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 225 0xffffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000, 226 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000, 227 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000, 228 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000, 229 0x00310000, 0x00320000, 0x00330000, 0xffffffff, 0xffffffff, 0xffffffff, 230 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 231 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 232 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 233 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 234 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 235 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 236 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 237 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 238 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 239 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 240 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 241 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 242 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 243 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 244 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 245 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 246 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 247 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 248 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 249 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 250 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 251 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 252 }; 253 254 #elif BYTE_ORDER == BIG_ENDIAN 255 256 /* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */ 257 258 const uint32_t base64_table_dec_32bit_d0[256] = { 259 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 260 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 261 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 262 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 263 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 264 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 265 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 266 0xffffffff, 0xf8000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xfc000000, 267 0xd0000000, 0xd4000000, 0xd8000000, 0xdc000000, 0xe0000000, 0xe4000000, 268 0xe8000000, 0xec000000, 0xf0000000, 0xf4000000, 0xffffffff, 0xffffffff, 269 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 270 0x04000000, 0x08000000, 0x0c000000, 0x10000000, 0x14000000, 0x18000000, 271 0x1c000000, 0x20000000, 0x24000000, 0x28000000, 0x2c000000, 0x30000000, 272 0x34000000, 0x38000000, 0x3c000000, 0x40000000, 0x44000000, 0x48000000, 273 0x4c000000, 0x50000000, 0x54000000, 0x58000000, 0x5c000000, 0x60000000, 274 0x64000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 275 0xffffffff, 0x68000000, 0x6c000000, 0x70000000, 0x74000000, 0x78000000, 276 0x7c000000, 0x80000000, 0x84000000, 0x88000000, 0x8c000000, 0x90000000, 277 0x94000000, 0x98000000, 0x9c000000, 0xa0000000, 0xa4000000, 0xa8000000, 278 0xac000000, 0xb0000000, 0xb4000000, 0xb8000000, 0xbc000000, 0xc0000000, 279 0xc4000000, 0xc8000000, 0xcc000000, 0xffffffff, 0xffffffff, 0xffffffff, 280 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 281 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 282 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 283 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 284 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 285 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 286 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 287 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 288 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 289 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 290 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 291 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 292 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 293 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 294 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 295 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 296 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 297 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 298 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 299 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 300 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 301 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 302 }; 303 304 const uint32_t base64_table_dec_32bit_d1[256] = { 305 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 306 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 307 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 308 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 309 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 310 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 311 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 312 0xffffffff, 0x03e00000, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f00000, 313 0x03400000, 0x03500000, 0x03600000, 0x03700000, 0x03800000, 0x03900000, 314 0x03a00000, 0x03b00000, 0x03c00000, 0x03d00000, 0xffffffff, 0xffffffff, 315 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 316 0x00100000, 0x00200000, 0x00300000, 0x00400000, 0x00500000, 0x00600000, 317 0x00700000, 0x00800000, 0x00900000, 0x00a00000, 0x00b00000, 0x00c00000, 318 0x00d00000, 0x00e00000, 0x00f00000, 0x01000000, 0x01100000, 0x01200000, 319 0x01300000, 0x01400000, 0x01500000, 0x01600000, 0x01700000, 0x01800000, 320 0x01900000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 321 0xffffffff, 0x01a00000, 0x01b00000, 0x01c00000, 0x01d00000, 0x01e00000, 322 0x01f00000, 0x02000000, 0x02100000, 0x02200000, 0x02300000, 0x02400000, 323 0x02500000, 0x02600000, 0x02700000, 0x02800000, 0x02900000, 0x02a00000, 324 0x02b00000, 0x02c00000, 0x02d00000, 0x02e00000, 0x02f00000, 0x03000000, 325 0x03100000, 0x03200000, 0x03300000, 0xffffffff, 0xffffffff, 0xffffffff, 326 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 327 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 328 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 329 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 330 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 331 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 332 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 333 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 334 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 335 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 336 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 337 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 338 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 339 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 340 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 341 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 342 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 343 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 344 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 345 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 346 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 347 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 348 }; 349 350 const uint32_t base64_table_dec_32bit_d2[256] = { 351 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 352 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 353 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 354 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 355 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 356 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 357 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 358 0xffffffff, 0x000f8000, 0xffffffff, 0xffffffff, 0xffffffff, 0x000fc000, 359 0x000d0000, 0x000d4000, 0x000d8000, 0x000dc000, 0x000e0000, 0x000e4000, 360 0x000e8000, 0x000ec000, 0x000f0000, 0x000f4000, 0xffffffff, 0xffffffff, 361 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 362 0x00004000, 0x00008000, 0x0000c000, 0x00010000, 0x00014000, 0x00018000, 363 0x0001c000, 0x00020000, 0x00024000, 0x00028000, 0x0002c000, 0x00030000, 364 0x00034000, 0x00038000, 0x0003c000, 0x00040000, 0x00044000, 0x00048000, 365 0x0004c000, 0x00050000, 0x00054000, 0x00058000, 0x0005c000, 0x00060000, 366 0x00064000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 367 0xffffffff, 0x00068000, 0x0006c000, 0x00070000, 0x00074000, 0x00078000, 368 0x0007c000, 0x00080000, 0x00084000, 0x00088000, 0x0008c000, 0x00090000, 369 0x00094000, 0x00098000, 0x0009c000, 0x000a0000, 0x000a4000, 0x000a8000, 370 0x000ac000, 0x000b0000, 0x000b4000, 0x000b8000, 0x000bc000, 0x000c0000, 371 0x000c4000, 0x000c8000, 0x000cc000, 0xffffffff, 0xffffffff, 0xffffffff, 372 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 373 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 374 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 375 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 376 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 377 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 378 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 379 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 380 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 381 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 382 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 383 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 384 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 385 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 386 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 387 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 388 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 389 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 390 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 391 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 392 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 393 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 394 }; 395 396 397 const uint32_t base64_table_dec_32bit_d3[256] = { 398 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 399 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 400 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 401 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 402 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 403 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 404 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 405 0xffffffff, 0x00003e00, 0xffffffff, 0xffffffff, 0xffffffff, 0x00003f00, 406 0x00003400, 0x00003500, 0x00003600, 0x00003700, 0x00003800, 0x00003900, 407 0x00003a00, 0x00003b00, 0x00003c00, 0x00003d00, 0xffffffff, 0xffffffff, 408 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 409 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 410 0x00000700, 0x00000800, 0x00000900, 0x00000a00, 0x00000b00, 0x00000c00, 411 0x00000d00, 0x00000e00, 0x00000f00, 0x00001000, 0x00001100, 0x00001200, 412 0x00001300, 0x00001400, 0x00001500, 0x00001600, 0x00001700, 0x00001800, 413 0x00001900, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 414 0xffffffff, 0x00001a00, 0x00001b00, 0x00001c00, 0x00001d00, 0x00001e00, 415 0x00001f00, 0x00002000, 0x00002100, 0x00002200, 0x00002300, 0x00002400, 416 0x00002500, 0x00002600, 0x00002700, 0x00002800, 0x00002900, 0x00002a00, 417 0x00002b00, 0x00002c00, 0x00002d00, 0x00002e00, 0x00002f00, 0x00003000, 418 0x00003100, 0x00003200, 0x00003300, 0xffffffff, 0xffffffff, 0xffffffff, 419 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 420 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 421 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 422 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 423 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 424 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 425 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 426 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 427 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 428 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 429 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 430 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 431 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 432 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 433 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 434 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 435 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 436 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 437 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 438 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 439 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 440 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff 441 }; 442 443 #else 444 445 # error "byte order unknown" 446 447 #endif // LITTLE_ENDIAN 448 449 static really_inline int 450 dec_loop_generic_32_inner (const uint8_t **s, uint8_t **o, size_t *rounds) 451 { 452 const uint32_t str 453 = base64_table_dec_32bit_d0[(*s)[0]] 454 | base64_table_dec_32bit_d1[(*s)[1]] 455 | base64_table_dec_32bit_d2[(*s)[2]] 456 | base64_table_dec_32bit_d3[(*s)[3]]; 457 458 #if BYTE_ORDER == LITTLE_ENDIAN 459 460 // LUTs for little-endian set MSB in case of invalid character: 461 if (str & UINT32_C(0x80000000)) { 462 return 0; 463 } 464 #else 465 // LUTs for big-endian set LSB in case of invalid character: 466 if (str & UINT32_C(1)) { 467 return 0; 468 } 469 #endif 470 // Store the output: 471 memcpy(*o, &str, sizeof (str)); 472 473 *s += 4; 474 *o += 3; 475 *rounds -= 1; 476 477 return 1; 478 } 479 480 static really_inline void 481 dec_loop_generic_32 (const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen) 482 { 483 if (*slen < 8) { 484 return; 485 } 486 487 // Process blocks of 4 bytes per round. Because one extra zero byte is 488 // written after the output, ensure that there will be at least 4 bytes 489 // of input data left to cover the gap. (Two data bytes and up to two 490 // end-of-string markers.) 491 size_t rounds = (*slen - 4) / 4; 492 493 *slen -= rounds * 4; // 4 bytes consumed per round 494 *olen += rounds * 3; // 3 bytes produced per round 495 496 do { 497 if (rounds >= 8) { 498 if (dec_loop_generic_32_inner(s, o, &rounds) && 499 dec_loop_generic_32_inner(s, o, &rounds) && 500 dec_loop_generic_32_inner(s, o, &rounds) && 501 dec_loop_generic_32_inner(s, o, &rounds) && 502 dec_loop_generic_32_inner(s, o, &rounds) && 503 dec_loop_generic_32_inner(s, o, &rounds) && 504 dec_loop_generic_32_inner(s, o, &rounds) && 505 dec_loop_generic_32_inner(s, o, &rounds)) { 506 continue; 507 } 508 break; 509 } 510 if (rounds >= 4) { 511 if (dec_loop_generic_32_inner(s, o, &rounds) && 512 dec_loop_generic_32_inner(s, o, &rounds) && 513 dec_loop_generic_32_inner(s, o, &rounds) && 514 dec_loop_generic_32_inner(s, o, &rounds)) { 515 continue; 516 } 517 break; 518 } 519 if (rounds >= 2) { 520 if (dec_loop_generic_32_inner(s, o, &rounds) && 521 dec_loop_generic_32_inner(s, o, &rounds)) { 522 continue; 523 } 524 break; 525 } 526 dec_loop_generic_32_inner(s, o, &rounds); 527 break; 528 529 } while (rounds > 0); 530 531 // Adjust for any rounds that were skipped: 532 *slen += rounds * 4; 533 *olen -= rounds * 3; 534 } 535 536 nonnull((1,2,4,5)) 537 static really_inline int base64_stream_decode( 538 struct base64_state *state, 539 const char *src, 540 size_t srclen, 541 uint8_t *out, 542 size_t *outlen) 543 { 544 int ret = 0; 545 const uint8_t *s = (const uint8_t *) src; 546 uint8_t *o = (uint8_t *) out; 547 uint8_t q; 548 549 // Use local temporaries to avoid cache thrashing: 550 size_t olen = 0; 551 size_t slen = srclen; 552 struct base64_state st; 553 st.eof = state->eof; 554 st.bytes = state->bytes; 555 st.carry = state->carry; 556 557 // If we previously saw an EOF or an invalid character, bail out: 558 if (st.eof) { 559 *outlen = 0; 560 ret = 0; 561 // If there was a trailing '=' to check, check it: 562 if (slen && (st.eof == BASE64_AEOF)) { 563 state->bytes = 0; 564 state->eof = BASE64_EOF; 565 ret = ((base64_table_dec_8bit[*s++] == 254) && (slen == 1)) ? 1 : 0; 566 } 567 return ret; 568 } 569 570 // Turn four 6-bit numbers into three bytes: 571 // out[0] = 11111122 572 // out[1] = 22223333 573 // out[2] = 33444444 574 575 // Duff's device again: 576 switch (st.bytes) 577 { 578 #if defined(__SUNPRO_C) 579 #pragma error_messages(off, E_STATEMENT_NOT_REACHED) 580 #endif 581 for (;;) 582 #if defined(__SUNPRO_C) 583 #pragma error_messages(default, E_STATEMENT_NOT_REACHED) 584 #endif 585 { 586 case 0: 587 dec_loop_generic_32(&s, &slen, &o, &olen); 588 if (slen-- == 0) { 589 ret = 1; 590 break; 591 } 592 if ((q = base64_table_dec_8bit[*s++]) >= 254) { 593 st.eof = BASE64_EOF; 594 // Treat character '=' as invalid for byte 0: 595 break; 596 } 597 st.carry = (uint8_t)(q << 2); 598 st.bytes++; 599 600 // fallthrough 601 602 case 1: 603 if (slen-- == 0) { 604 ret = 1; 605 break; 606 } 607 if ((q = base64_table_dec_8bit[*s++]) >= 254) { 608 st.eof = BASE64_EOF; 609 // Treat character '=' as invalid for byte 1: 610 break; 611 } 612 *o++ = st.carry | (q >> 4); 613 st.carry = (uint8_t)(q << 4); 614 st.bytes++; 615 olen++; 616 617 // fallthrough 618 619 case 2: 620 if (slen-- == 0) { 621 ret = 1; 622 break; 623 } 624 if ((q = base64_table_dec_8bit[*s++]) >= 254) { 625 st.bytes++; 626 // When q == 254, the input char is '='. 627 // Check if next byte is also '=': 628 if (q == 254) { 629 if (slen-- != 0) { 630 st.bytes = 0; 631 // EOF: 632 st.eof = BASE64_EOF; 633 q = base64_table_dec_8bit[*s++]; 634 ret = ((q == 254) && (slen == 0)) ? 1 : 0; 635 break; 636 } 637 else { 638 // Almost EOF 639 st.eof = BASE64_AEOF; 640 ret = 1; 641 break; 642 } 643 } 644 // If we get here, there was an error: 645 break; 646 } 647 *o++ = st.carry | (q >> 2); 648 st.carry = (uint8_t)(q << 6); 649 st.bytes++; 650 olen++; 651 652 // fallthrough 653 654 case 3: 655 if (slen-- == 0) { 656 ret = 1; 657 break; 658 } 659 if ((q = base64_table_dec_8bit[*s++]) >= 254) { 660 st.bytes = 0; 661 st.eof = BASE64_EOF; 662 // When q == 254, the input char is '='. Return 1 and EOF. 663 // When q == 255, the input char is invalid. Return 0 and EOF. 664 ret = ((q == 254) && (slen == 0)) ? 1 : 0; 665 break; 666 } 667 *o++ = st.carry | q; 668 st.carry = 0; 669 st.bytes = 0; 670 olen++; 671 } 672 } 673 674 state->eof = st.eof; 675 state->bytes = st.bytes; 676 state->carry = st.carry; 677 *outlen = olen; 678 return ret; 679 } 680 681 nonnull((1,3,4)) 682 static really_inline int base64_decode( 683 const char *src, 684 size_t srclen, 685 uint8_t *out, 686 size_t *outlen) 687 { 688 struct base64_state state = { .eof = 0, .bytes = 0, .carry = 0 }; 689 return base64_stream_decode(&state, src, srclen, out, outlen) & !state.bytes; 690 } 691 692 nonnull_all 693 static really_inline int32_t parse_base64_sequence( 694 parser_t *parser, 695 const type_info_t *type, 696 const rdata_info_t *item, 697 rdata_t *rdata, 698 token_t *token) 699 { 700 if (is_contiguous(token)) { 701 struct base64_state state = { .eof = 0, .bytes = 0, .carry = 0 }; 702 703 do { 704 size_t length = token->length / 4; 705 if (((uintptr_t)rdata->limit - (uintptr_t)rdata->octets) / 3 < length) 706 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type)); 707 if (!base64_stream_decode(&state, token->data, token->length, rdata->octets, &length)) 708 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type)); 709 rdata->octets += length; 710 take(parser, token); 711 } while (is_contiguous(token)); 712 713 // incomplete base64 sequence 714 if (state.bytes) 715 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type)); 716 } 717 718 return have_delimiter(parser, type, token); 719 } 720 721 nonnull_all 722 static really_inline int32_t parse_base64( 723 parser_t *parser, 724 const type_info_t *type, 725 const rdata_info_t *item, 726 rdata_t *rdata, 727 const token_t *token) 728 { 729 size_t length = token->length / 4; 730 if (((uintptr_t)rdata->limit - (uintptr_t)rdata->octets) / 3 < length) 731 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type)); 732 if (!base64_decode(token->data, token->length, rdata->octets, &length)) 733 SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type)); 734 rdata->octets += length; 735 return 0; 736 } 737 738 #endif // BASE64_H 739