diff libtomcrypt/src/encauth/ccm/ccm_add_nonce.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libtomcrypt/src/encauth/ccm/ccm_add_nonce.c	Fri Feb 09 21:44:05 2018 +0800
@@ -0,0 +1,113 @@
+/* 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_CCM_MODE
+
+/**
+  Add nonce data to the CCM state
+  @param ccm       The CCM state
+  @param nonce     The nonce data to add
+  @param noncelen  The length of the nonce
+  @return CRYPT_OK on success
+ */
+int ccm_add_nonce(ccm_state *ccm,
+                  const unsigned char *nonce,     unsigned long noncelen)
+{
+   unsigned long x, y, len;
+   int           err;
+
+   LTC_ARGCHK(ccm   != NULL);
+   LTC_ARGCHK(nonce != NULL);
+
+   /* increase L to match the nonce len */
+   ccm->noncelen = (noncelen > 13) ? 13 : noncelen;
+   if ((15 - ccm->noncelen) > ccm->L) {
+      ccm->L = 15 - ccm->noncelen;
+   }
+
+   /* decrease noncelen to match L */
+   if ((ccm->noncelen + ccm->L) > 15) {
+      ccm->noncelen = 15 - ccm->L;
+   }
+
+   /* form B_0 == flags | Nonce N | l(m) */
+   x = 0;
+   ccm->PAD[x++] = (unsigned char)(((ccm->aadlen > 0) ? (1<<6) : 0) |
+                   (((ccm->taglen - 2)>>1)<<3)        |
+                   (ccm->L-1));
+
+   /* nonce */
+   for (y = 0; y < (16 - (ccm->L + 1)); y++) {
+      ccm->PAD[x++] = nonce[y];
+   }
+
+   /* store len */
+   len = ccm->ptlen;
+
+   /* shift len so the upper bytes of len are the contents of the length */
+   for (y = ccm->L; y < 4; y++) {
+      len <<= 8;
+   }
+
+   /* store l(m) (only store 32-bits) */
+   for (y = 0; ccm->L > 4 && (ccm->L-y)>4; y++) {
+      ccm->PAD[x++] = 0;
+   }
+   for (; y < ccm->L; y++) {
+      ccm->PAD[x++] = (unsigned char)((len >> 24) & 255);
+      len <<= 8;
+   }
+
+   /* encrypt PAD */
+   if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* handle header */
+   ccm->x = 0;
+   if (ccm->aadlen > 0) {
+      /* store length */
+      if (ccm->aadlen < ((1UL<<16) - (1UL<<8))) {
+         ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255;
+         ccm->PAD[ccm->x++] ^= ccm->aadlen & 255;
+      } else {
+         ccm->PAD[ccm->x++] ^= 0xFF;
+         ccm->PAD[ccm->x++] ^= 0xFE;
+         ccm->PAD[ccm->x++] ^= (ccm->aadlen>>24) & 255;
+         ccm->PAD[ccm->x++] ^= (ccm->aadlen>>16) & 255;
+         ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255;
+         ccm->PAD[ccm->x++] ^= ccm->aadlen & 255;
+      }
+   }
+
+   /* setup the ctr counter */
+   x = 0;
+
+   /* flags */
+   ccm->ctr[x++] = (unsigned char)ccm->L-1;
+
+   /* nonce */
+   for (y = 0; y < (16 - (ccm->L+1)); ++y) {
+      ccm->ctr[x++] = nonce[y];
+   }
+   /* offset */
+   while (x < 16) {
+      ccm->ctr[x++] = 0;
+   }
+
+   ccm->CTRlen = 16;
+   return CRYPT_OK;
+}
+
+#endif
+
+/* ref:         $Format:%D$ */
+/* git commit:  $Format:%H$ */
+/* commit time: $Format:%ai$ */