diff libtomcrypt/src/modes/ctr/ctr_encrypt.c @ 1711:e9dba7abd939

Merge libtomcrypt v1.18.2
author Matt Johnston <matt@ucc.asn.au>
date Wed, 10 Jun 2020 23:16:13 +0800
parents 6dba84798cd5
children
line wrap: on
line diff
--- a/libtomcrypt/src/modes/ctr/ctr_encrypt.c	Wed Jun 10 23:01:33 2020 +0800
+++ b/libtomcrypt/src/modes/ctr/ctr_encrypt.c	Wed Jun 10 23:16:13 2020 +0800
@@ -17,47 +17,17 @@
 #ifdef LTC_CTR_MODE
 
 /**
-  CTR encrypt
+  CTR encrypt software implementation
   @param pt     Plaintext
   @param ct     [out] Ciphertext
   @param len    Length of plaintext (octets)
   @param ctr    CTR state
   @return CRYPT_OK if successful
 */
-int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
+static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
 {
    int x, err;
 
-   LTC_ARGCHK(pt != NULL);
-   LTC_ARGCHK(ct != NULL);
-   LTC_ARGCHK(ctr != NULL);
-
-   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
-       return err;
-   }
-
-   /* is blocklen/padlen valid? */
-   if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
-       ctr->padlen   < 0 || ctr->padlen   > (int)sizeof(ctr->pad)) {
-      return CRYPT_INVALID_ARG;
-   }
-
-#ifdef LTC_FAST
-   if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
-      return CRYPT_INVALID_ARG;
-   }
-#endif
-
-   /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
-   if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
-      if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
-         return err;
-      }
-      pt += (len / ctr->blocklen) * ctr->blocklen;
-      ct += (len / ctr->blocklen) * ctr->blocklen;
-      len %= ctr->blocklen;
-   }
-
    while (len) {
       /* is the pad empty? */
       if (ctr->padlen == ctr->blocklen) {
@@ -87,7 +57,7 @@
          ctr->padlen = 0;
       }
 #ifdef LTC_FAST
-      if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) {
+      if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {
          for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
             *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^
                                                            *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));
@@ -105,6 +75,63 @@
    return CRYPT_OK;
 }
 
+/**
+  CTR encrypt
+  @param pt     Plaintext
+  @param ct     [out] Ciphertext
+  @param len    Length of plaintext (octets)
+  @param ctr    CTR state
+  @return CRYPT_OK if successful
+*/
+int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
+{
+   int err, fr;
+
+   LTC_ARGCHK(pt != NULL);
+   LTC_ARGCHK(ct != NULL);
+   LTC_ARGCHK(ctr != NULL);
+
+   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
+       return err;
+   }
+
+   /* is blocklen/padlen valid? */
+   if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||
+       (ctr->padlen   < 0) || (ctr->padlen   > (int)sizeof(ctr->pad))) {
+      return CRYPT_INVALID_ARG;
+   }
+
+#ifdef LTC_FAST
+   if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
+      return CRYPT_INVALID_ARG;
+   }
+#endif
+
+   /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
+   if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {
+     if (ctr->padlen < ctr->blocklen) {
+       fr = ctr->blocklen - ctr->padlen;
+       if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {
+          return err;
+       }
+       pt += fr;
+       ct += fr;
+       len -= fr;
+     }
+
+     if (len >= (unsigned long)ctr->blocklen) {
+       if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
+          return err;
+       }
+       pt += (len / ctr->blocklen) * ctr->blocklen;
+       ct += (len / ctr->blocklen) * ctr->blocklen;
+       len %= ctr->blocklen;
+     }
+   }
+
+   return _ctr_encrypt(pt, ct, len, ctr);
+}
+
 #endif
 
 /* ref:         $Format:%D$ */