/* * base32.h -- Base32 decoder * * Copyright (c) 2022, NLnet Labs. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause * */ #ifndef BASE32_H #define BASE32_H static const uint8_t b32rmap[256] = { 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */ 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, /* 8 - 15 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 - 23 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 24 - 31 */ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 32 - 39 */ 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* 40 - 47 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 48 - 55 */ 0x08, 0x09, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, /* 56 - 63 */ 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* 64 - 71 */ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* 72 - 79 */ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xff, /* 80 - 87 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 88 - 95 */ 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* 96 - 103 */ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* 104 - 111 */ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0xff, /* 112 - 119 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 120 - 127 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 128 - 135 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 136 - 143 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 144 - 151 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 152 - 159 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 160 - 167 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 168 - 175 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 176 - 183 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 184 - 191 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 192 - 199 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 200 - 207 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 208 - 215 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 216 - 223 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 224 - 231 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 232 - 239 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 240 - 247 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 248 - 255 */ }; static const uint8_t b32rmap_special = 0xf0; nonnull_all static really_inline int32_t parse_base32( parser_t *parser, const type_info_t *type, const rdata_info_t *field, rdata_t *rdata, const token_t *token) { uint32_t state = 0; size_t length = (token->length * 5) / 8; if (length > 255 || (uintptr_t)rdata->limit - (uintptr_t)rdata->octets < (length + 1)) SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); *rdata->octets++ = (uint8_t)length; const char *p = token->data; for (;; p++) { const uint8_t ofs = b32rmap[(uint8_t)*p]; if (ofs >= b32rmap_special) break; switch (state) { case 0: *rdata->octets = (uint8_t)(ofs << 3); state = 1; break; case 1: *rdata->octets++ |= (uint8_t)(ofs >> 2); *rdata->octets = (uint8_t)(ofs << 6); state = 2; break; case 2: *rdata->octets |= (uint8_t)(ofs << 1); state = 3; break; case 3: *rdata->octets++ |= (uint8_t)(ofs >> 4); *rdata->octets = (uint8_t)(ofs << 4); state = 4; break; case 4: *rdata->octets++ |= (uint8_t)(ofs >> 1); *rdata->octets = (uint8_t)(ofs << 7); state = 5; break; case 5: *rdata->octets |= (uint8_t)(ofs << 2); state = 6; break; case 6: *rdata->octets++ |= (uint8_t)(ofs >> 3); *rdata->octets = (uint8_t)(ofs << 5); state = 7; break; case 7: *rdata->octets++ |= ofs; state = 0; break; } } if (p != token->data + token->length) SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(field), NAME(type)); return 0; } #endif // BASE32_H