Path: blob/master/libs/tomcrypt/src/modes/ctr/ctr_encrypt.c
5972 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file ctr_encrypt.c12CTR implementation, encrypt data, Tom St Denis13*/141516#ifdef LTC_CTR_MODE1718/**19CTR encrypt software implementation20@param pt Plaintext21@param ct [out] Ciphertext22@param len Length of plaintext (octets)23@param ctr CTR state24@return CRYPT_OK if successful25*/26static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)27{28int x, err;2930while (len) {31/* is the pad empty? */32if (ctr->padlen == ctr->blocklen) {33/* increment counter */34if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {35/* little-endian */36for (x = 0; x < ctr->ctrlen; x++) {37ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;38if (ctr->ctr[x] != (unsigned char)0) {39break;40}41}42} else {43/* big-endian */44for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {45ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;46if (ctr->ctr[x] != (unsigned char)0) {47break;48}49}50}5152/* encrypt it */53if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {54return err;55}56ctr->padlen = 0;57}58#ifdef LTC_FAST59if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) {60for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {61*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^62*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x));63}64pt += ctr->blocklen;65ct += ctr->blocklen;66len -= ctr->blocklen;67ctr->padlen = ctr->blocklen;68continue;69}70#endif71*ct++ = *pt++ ^ ctr->pad[ctr->padlen++];72--len;73}74return CRYPT_OK;75}7677/**78CTR encrypt79@param pt Plaintext80@param ct [out] Ciphertext81@param len Length of plaintext (octets)82@param ctr CTR state83@return CRYPT_OK if successful84*/85int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)86{87int err, fr;8889LTC_ARGCHK(pt != NULL);90LTC_ARGCHK(ct != NULL);91LTC_ARGCHK(ctr != NULL);9293if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {94return err;95}9697/* is blocklen/padlen valid? */98if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) ||99(ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) {100return CRYPT_INVALID_ARG;101}102103#ifdef LTC_FAST104if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {105return CRYPT_INVALID_ARG;106}107#endif108109/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */110if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) {111if (ctr->padlen < ctr->blocklen) {112fr = ctr->blocklen - ctr->padlen;113if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) {114return err;115}116pt += fr;117ct += fr;118len -= fr;119}120121if (len >= (unsigned long)ctr->blocklen) {122if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {123return err;124}125pt += (len / ctr->blocklen) * ctr->blocklen;126ct += (len / ctr->blocklen) * ctr->blocklen;127len %= ctr->blocklen;128}129}130131return _ctr_encrypt(pt, ct, len, ctr);132}133134#endif135136137