Path: blob/master/libs/tomcrypt/src/modes/ctr/ctr_start.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_start.c12CTR implementation, start chain, Tom St Denis13*/141516#ifdef LTC_CTR_MODE1718/**19Initialize a CTR context20@param cipher The index of the cipher desired21@param IV The initialization vector22@param key The secret key23@param keylen The length of the secret key (octets)24@param num_rounds Number of rounds in the cipher desired (0 for default)25@param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN)26@param ctr The CTR state to initialize27@return CRYPT_OK if successful28*/29int ctr_start( int cipher,30const unsigned char *IV,31const unsigned char *key, int keylen,32int num_rounds, int ctr_mode,33symmetric_CTR *ctr)34{35int x, err;3637LTC_ARGCHK(IV != NULL);38LTC_ARGCHK(key != NULL);39LTC_ARGCHK(ctr != NULL);4041/* bad param? */42if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {43return err;44}4546/* ctrlen == counter width */47ctr->ctrlen = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length;48if (ctr->ctrlen > cipher_descriptor[cipher].block_length) {49return CRYPT_INVALID_ARG;50}5152if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) {53ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen;54}5556/* setup cipher */57if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {58return err;59}6061/* copy ctr */62ctr->blocklen = cipher_descriptor[cipher].block_length;63ctr->cipher = cipher;64ctr->padlen = 0;65ctr->mode = ctr_mode & 0x1000;66for (x = 0; x < ctr->blocklen; x++) {67ctr->ctr[x] = IV[x];68}6970if (ctr_mode & LTC_CTR_RFC3686) {71/* increment the IV as per RFC 3686 */72if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {73/* little-endian */74for (x = 0; x < ctr->ctrlen; x++) {75ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;76if (ctr->ctr[x] != (unsigned char)0) {77break;78}79}80} else {81/* big-endian */82for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) {83ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;84if (ctr->ctr[x] != (unsigned char)0) {85break;86}87}88}89}9091return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);92}9394#endif959697