浏览代码

add base16_{de,en}code()

Steffen Jaeckel 7 年之前
父节点
当前提交
3d99d9b443

+ 2 - 0
src/headers/tomcrypt_custom.h

@@ -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*/

+ 9 - 0
src/headers/tomcrypt_misc.h

@@ -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
 

+ 65 - 0
src/misc/base16/base16_decode.c

@@ -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$ */

+ 71 - 0
src/misc/base16/base16_encode.c

@@ -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$ */

+ 3 - 0
src/misc/crypt/crypt.c

@@ -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 - 0
tests/base16_test.c

@@ -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$ */

+ 3 - 0
tests/misc_test.c

@@ -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

+ 1 - 0
tests/tomcrypt_test.h

@@ -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);