blob: 7408d05c0ce38b4a31a4c0652dcfacf687c297dc [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt_private.h"
/**
@file base16_decode.c
Base16/Hex decode a string.
Based on https://stackoverflow.com/a/23898449
Adapted for libtomcrypt by Steffen Jaeckel
*/
#ifdef LTC_BASE16
/**
Base16 decode a string
@param in The Base16 string to decode
@param inlen The length of the Base16 data
@param out [out] The destination of the binary decoded data
@param outlen [in/out] The max size and resulting size of the decoded data
@return CRYPT_OK if successful
*/
int base16_decode(const char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long pos, out_len;
unsigned char idx0, idx1;
char in0, in1;
const unsigned char hashmap[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* @ABCDEFG */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* HIJKLMNO */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* PQRSTUVW */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* `abcdefg */
};
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((inlen % 2) == 1) return CRYPT_INVALID_PACKET;
out_len = *outlen * 2;
for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < inlen)); pos += 2) {
in0 = in[pos + 0];
in1 = in[pos + 1];
if ((in0 < '0') || (in0 > 'g')) return CRYPT_INVALID_PACKET;
if ((in1 < '0') || (in1 > 'g')) return CRYPT_INVALID_PACKET;
idx0 = (unsigned char) (in0 & 0x1F) ^ 0x10;
idx1 = (unsigned char) (in1 & 0x1F) ^ 0x10;
if (hashmap[idx0] == 0xff) return CRYPT_INVALID_PACKET;
if (hashmap[idx1] == 0xff) return CRYPT_INVALID_PACKET;
out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1];
}
*outlen = pos / 2;
return CRYPT_OK;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */