summaryrefslogtreecommitdiff
path: root/libtomcrypt/src/modes/ctr/ctr_encrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtomcrypt/src/modes/ctr/ctr_encrypt.c')
-rw-r--r--libtomcrypt/src/modes/ctr/ctr_encrypt.c93
1 files changed, 60 insertions, 33 deletions
diff --git a/libtomcrypt/src/modes/ctr/ctr_encrypt.c b/libtomcrypt/src/modes/ctr/ctr_encrypt.c
index 7319cf5..eb7328c 100644
--- a/libtomcrypt/src/modes/ctr/ctr_encrypt.c
+++ b/libtomcrypt/src/modes/ctr/ctr_encrypt.c
@@ -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 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
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 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
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$ */