Sfoglia il codice sorgente

add padding module

Steffen Jaeckel 8 anni fa
parent
commit
82482119df

+ 2 - 0
src/headers/tomcrypt_custom.h

@@ -464,6 +464,8 @@
 
 #define LTC_CRC32
 
+#define LTC_PADDING
+
 #endif /* LTC_NO_MISC */
 
 /* cleanup */

+ 23 - 0
src/headers/tomcrypt_misc.h

@@ -135,6 +135,29 @@ void crc32_finish(crc32_state *ctx, void *hash, unsigned long size);
 int crc32_test(void);
 #endif
 
+
+#ifdef LTC_PADDING
+
+enum padding_type {
+   LTC_PAD_PKCS7        = 0x0000U,
+#ifdef LTC_RNG_GET_BYTES
+   LTC_PAD_ISO_10126    = 0x1000U,
+#endif
+   LTC_PAD_ANSI_X923    = 0x2000U,
+   LTC_PAD_ONE_AND_ZERO = 0x8000U,
+   LTC_PAD_ZERO         = 0x9000U,
+   LTC_PAD_ZERO_ALWAYS  = 0xA000U,
+};
+
+int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode);
+int padding_depad(unsigned char *data, unsigned long *length, unsigned long mode);
+
+#ifdef LTC_SOURCE
+/* internal helper functions */
+#define LTC_PAD_MASK       (0xF000U)
+#endif
+#endif  /* LTC_PADDING */
+
 int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which);
 
 /* ref:         $Format:%D$ */

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

@@ -429,6 +429,9 @@ const char *crypt_build_settings =
 #if defined(LTC_PKCS_5)
     " PKCS#5 "
 #endif
+#if defined(LTC_PADDING)
+    " PADDING "
+#endif
 #if defined(LTC_HKDF)
     " HKDF "
 #endif

+ 15 - 0
src/misc/crypt/crypt_constants.c

@@ -75,6 +75,21 @@ static const crypt_constant _crypt_constants[] = {
     {"LTC_PKCS_1", 0},
 #endif
 
+#ifdef LTC_PADDING
+    {"LTC_PADDING", 1},
+
+    _C_STRINGIFY(LTC_PAD_PKCS7),
+#ifdef LTC_RNG_GET_BYTES
+    _C_STRINGIFY(LTC_PAD_ISO_10126),
+#endif
+    _C_STRINGIFY(LTC_PAD_ANSI_X923),
+    _C_STRINGIFY(LTC_PAD_ONE_AND_ZERO),
+    _C_STRINGIFY(LTC_PAD_ZERO),
+    _C_STRINGIFY(LTC_PAD_ZERO_ALWAYS),
+#else
+    {"LTC_PADDING", 0},
+#endif
+
 #ifdef LTC_MRSA
     {"LTC_MRSA", 1},
 #else

+ 94 - 0
src/misc/padding/padding_depad.c

@@ -0,0 +1,94 @@
+/* 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"
+
+#ifdef LTC_PADDING
+
+/**
+   Remove padding from your data
+
+      This depads your data.
+
+   @param data     The data to depad
+   @param length   [in/out] The size of the data before/after (removing padding)
+   @param mode     One of the LTC_PAD_xx flags
+   @return CRYPT_OK on success
+*/
+int padding_depad(unsigned char *data, unsigned long *length, unsigned long mode)
+{
+   unsigned long padded_length, unpadded_length, n;
+   unsigned char pad;
+   enum padding_type type;
+
+   LTC_ARGCHK(data   != NULL);
+   LTC_ARGCHK(length != NULL);
+
+   padded_length = *length;
+
+   type = mode & LTC_PAD_MASK;
+
+   if (type < LTC_PAD_ONE_AND_ZERO) {
+      pad = data[padded_length - 1];
+
+      if (pad > padded_length) return CRYPT_INVALID_ARG;
+
+      unpadded_length = padded_length - pad;
+   } else {
+      /* init pad to calm old compilers */
+      pad = 0x0;
+      unpadded_length = padded_length;
+   }
+
+   switch (type) {
+      case LTC_PAD_ANSI_X923:
+         pad = 0x0;
+         /* FALLTHROUGH */
+      case LTC_PAD_PKCS7:
+         for (n = unpadded_length; n < padded_length - 1; ++n) {
+            if (data[n] != pad) return CRYPT_INVALID_PACKET;
+         }
+         break;
+#ifdef LTC_RNG_GET_BYTES
+      case LTC_PAD_ISO_10126:
+         /* nop */
+         break;
+#endif
+      case LTC_PAD_ONE_AND_ZERO:
+         while (unpadded_length > 0 && data[unpadded_length - 1] != 0x80) {
+            if (data[unpadded_length - 1] != 0x0) return CRYPT_INVALID_PACKET;
+            unpadded_length--;
+         }
+         if (unpadded_length == 0) return CRYPT_INVALID_PACKET;
+         unpadded_length--;
+         if (data[unpadded_length] != 0x80) return CRYPT_INVALID_PACKET;
+         break;
+      case LTC_PAD_ZERO:
+      case LTC_PAD_ZERO_ALWAYS:
+         while (unpadded_length > 0 && data[unpadded_length - 1] == 0x0) {
+            unpadded_length--;
+         }
+         if (type == LTC_PAD_ZERO_ALWAYS) {
+            if (unpadded_length == padded_length) return CRYPT_INVALID_PACKET;
+            if (data[unpadded_length] != 0x0) return CRYPT_INVALID_PACKET;
+         }
+         break;
+      default:
+         return CRYPT_INVALID_ARG;
+   }
+
+   *length = unpadded_length;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */

+ 146 - 0
src/misc/padding/padding_pad.c

@@ -0,0 +1,146 @@
+/* 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"
+
+#ifdef LTC_PADDING
+
+/**
+   Determine the to-be-padded length.
+
+   @param length     [in/out] The size of the data before/after padding
+   @param mode       Mask of (LTC_PAD_xxx | block_length)
+   @return CRYPT_OK on success
+*/
+static int _padding_padded_length(unsigned long *length, unsigned long mode)
+{
+   enum padding_type padding;
+   unsigned char pad, block_length, r, t;
+
+   LTC_ARGCHK(length != NULL);
+
+   block_length = mode & 0xff;
+   padding = mode & LTC_PAD_MASK;
+   r = *length % block_length;
+
+   switch (padding) {
+      case LTC_PAD_ZERO:
+         if (r == 0) {
+            t = 0;
+            break;
+         }
+         /* FALLTHROUGH */
+      case LTC_PAD_PKCS7:
+      case LTC_PAD_ONE_AND_ZERO:
+      case LTC_PAD_ZERO_ALWAYS:
+         t = 1;
+         break;
+#ifdef LTC_RNG_GET_BYTES
+      case LTC_PAD_ISO_10126:
+         do {
+            if (rng_get_bytes(&t, sizeof(t), NULL) != sizeof(t)) {
+               return CRYPT_ERROR_READPRNG;
+            }
+            t %= (256 / block_length);
+         } while (t == 0);
+         break;
+#endif
+      case LTC_PAD_ANSI_X923:
+         if (block_length != 16) {
+            return CRYPT_INVALID_ARG;
+         }
+         t = 1;
+         break;
+      default:
+         return CRYPT_INVALID_ARG;
+   }
+
+   pad = (t * block_length) - r;
+
+   if ((pad == 0) && (padding != LTC_PAD_ZERO)) {
+      pad = block_length;
+   }
+
+   *length += pad;
+
+   return CRYPT_OK;
+}
+
+/**
+   Add padding to data.
+
+      This pads your data.
+
+   @param data          The data to depad
+   @param length        The size of the data before padding
+   @param padded_length [in/out] The size of the data available/after padding
+   @param mode          One of the LTC_PAD_xx flags
+   @return CRYPT_OK on success
+*/
+int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode)
+{
+   unsigned long diff, l;
+   enum padding_type type;
+   int err;
+
+   LTC_ARGCHK(data          != NULL);
+   LTC_ARGCHK(padded_length != NULL);
+
+   l = length;
+   if ((err = _padding_padded_length(&l, mode)) != CRYPT_OK) {
+      return err;
+   }
+
+   type = mode & LTC_PAD_MASK;
+
+   if (*padded_length < l) {
+      if (type != LTC_PAD_ISO_10126) *padded_length = l;
+      else *padded_length = length + 256;
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+
+   diff = l - length;
+   if (diff > 255) return CRYPT_INVALID_ARG;
+
+   switch (type) {
+      case LTC_PAD_PKCS7:
+         XMEMSET(&data[length], diff, diff);
+         break;
+#ifdef LTC_RNG_GET_BYTES
+      case LTC_PAD_ISO_10126:
+         if (rng_get_bytes(&data[length], diff-1, NULL) != diff-1) {
+            return CRYPT_ERROR_READPRNG;
+         }
+         data[l-1] =  diff;
+         break;
+#endif
+      case LTC_PAD_ANSI_X923:
+         XMEMSET(&data[length], 0, diff-1);
+         data[l-1] =  diff;
+         break;
+      case LTC_PAD_ONE_AND_ZERO:
+         XMEMSET(&data[length + 1], 0, diff);
+         data[length] =  0x80;
+         break;
+      case LTC_PAD_ZERO:
+      case LTC_PAD_ZERO_ALWAYS:
+         XMEMSET(&data[length], 0, diff);
+         break;
+      default:
+         return CRYPT_INVALID_ARG;
+   }
+   *padded_length = l;
+
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */