add base16_{de,en}code()

This commit is contained in:
Steffen Jaeckel 2018-03-22 15:44:01 +01:00
parent b026c23b0a
commit 3d99d9b443
8 changed files with 207 additions and 0 deletions

View file

@ -450,6 +450,8 @@
#define LTC_BASE64_URL
/* Base32 encoding/decoding */
#define LTC_BASE32
/* Base16/hex encoding/decoding */
#define LTC_BASE16
/* Keep LTC_NO_HKDF for compatibility reasons
* superseeded by LTC_NO_MISC*/

View file

@ -46,6 +46,15 @@ int base32_decode(const unsigned char *in, unsigned long inlen,
base32_alphabet id);
#endif
/* ---- BASE16 Routines ---- */
#ifdef LTC_BASE16
int base16_encode(const unsigned char *in, unsigned long inlen,
char *out, unsigned long *outlen,
int caps);
int base16_decode(const char *in,
unsigned char *out, unsigned long *outlen);
#endif
/* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */
#ifdef LTC_HKDF

View file

@ -0,0 +1,65 @@
/* 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.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 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 char *out, unsigned long *outlen)
{
unsigned long pos, in_len, out_len;
unsigned char idx0;
unsigned char idx1;
const unsigned char hashmap[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */
};
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
in_len = strlen(in);
if ((in_len % 2) == 1) return CRYPT_INVALID_PACKET;
out_len = *outlen * 2;
for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < in_len)); pos += 2) {
idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10;
idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10;
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$ */

View file

@ -0,0 +1,71 @@
/* 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.h"
/**
@file base16_encode.c
Base16/Hex encode a string, Steffen Jaeckel
*/
#ifdef LTC_BASE16
/**
Base16 encode a buffer
@param in The input buffer to encode
@param inlen The length of the input buffer
@param out [out] The destination of the Base16 encoded data
@param outlen [in/out] The max size and resulting size of the encoded data
@param caps Output 'a-f' on 0 and 'A-F' otherwise.
@return CRYPT_OK if successful
*/
int base16_encode(const unsigned char *in, unsigned long inlen,
char *out, unsigned long *outlen,
int caps)
{
unsigned long i, x;
const char *alphabet;
const char *alphabets[2] = {
"0123456789abcdef",
"0123456789ABCDEF",
};
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* check the sizes */
x = inlen * 2 + 1;
if (x < inlen) return CRYPT_OVERFLOW;
if (*outlen < x) {
*outlen = x;
return CRYPT_BUFFER_OVERFLOW;
}
*outlen = x;
if (caps == 0) alphabet = alphabets[0];
else alphabet = alphabets[1];
x -= 1;
for (i = 0; i < x; i += 2) {
out[i] = alphabet[(in[i/2] >> 4) & 0x0f];
out[i+1] = alphabet[in[i/2] & 0x0f];
}
out[x] = '\0';
return CRYPT_OK;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */

View file

@ -414,6 +414,9 @@ const char *crypt_build_settings =
#if defined(LTC_BASE32)
" BASE32 "
#endif
#if defined(LTC_BASE16)
" BASE16 "
#endif
#if defined(LTC_CRC32)
" CRC32 "
#endif

53
tests/base16_test.c Normal file
View file

@ -0,0 +1,53 @@
/* 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_test.h>
#ifdef LTC_BASE16
int base16_test(void)
{
unsigned char in[100], tmp[100];
char out[201];
unsigned char testin[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
const char *testout[2] = {
"0123456789abcdef",
"0123456789ABCDEF",
};
unsigned long x, l1, l2;
int idx;
for (idx = 0; idx < 2; idx++) {
for (x = 0; x < 100; x++) {
yarrow_read(in, x, &yarrow_prng);
l1 = sizeof(out);
DO(base16_encode(in, x, out, &l1, idx));
l2 = sizeof(tmp);
DO(base16_decode(out, tmp, &l2));
DO(do_compare_testvector(tmp, l2, in, x, "random base16", idx * 100 + x));
}
}
for (idx = 0; idx < 2; idx++) {
l1 = sizeof(out);
DO(base16_encode(testin, sizeof(testin), out, &l1, idx));
DO(do_compare_testvector(out, strlen(out), testout[idx], strlen(testout[idx]), "testout base16", idx));
l2 = sizeof(tmp);
DO(base16_decode(out, tmp, &l2));
DO(do_compare_testvector(tmp, l2, testin, sizeof(testin), "testin base16", idx));
}
return CRYPT_OK;
}
#endif
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */

View file

@ -22,6 +22,9 @@ int misc_test(void)
#ifdef LTC_BASE32
DO(base32_test());
#endif
#ifdef LTC_BASE16
DO(base16_test());
#endif
#ifdef LTC_ADLER32
DO(adler32_test());
#endif

View file

@ -39,6 +39,7 @@ int der_test(void);
int misc_test(void);
int base64_test(void);
int base32_test(void);
int base16_test(void);
int file_test(void);
int multi_test(void);
int prng_test(void);