Path: blob/master/libs/tomcrypt/src/encauth/ocb3/ocb3_encrypt_last.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*/89/**10@file ocb3_encrypt_last.c11OCB implementation, internal helper, by Karel Miko12*/13#include "tomcrypt.h"1415#ifdef LTC_OCB3_MODE1617/**18Finish an OCB (encryption) stream19@param ocb The OCB state20@param pt The remaining plaintext21@param ptlen The length of the plaintext (octets)22@param ct [out] The output buffer23@return CRYPT_OK if successful24*/25int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)26{27unsigned char iOffset_star[MAXBLOCKSIZE];28unsigned char iPad[MAXBLOCKSIZE];29int err, x, full_blocks, full_blocks_len, last_block_len;3031LTC_ARGCHK(ocb != NULL);32if (pt == NULL) LTC_ARGCHK(ptlen == 0);33if (ptlen != 0) {34LTC_ARGCHK(pt != NULL);35LTC_ARGCHK(ct != NULL);36}3738if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {39goto LBL_ERR;40}4142full_blocks = ptlen/ocb->block_len;43full_blocks_len = full_blocks * ocb->block_len;44last_block_len = ptlen - full_blocks_len;4546/* process full blocks first */47if (full_blocks>0) {48if ((err = ocb3_encrypt(ocb, pt, full_blocks_len, ct)) != CRYPT_OK) {49goto LBL_ERR;50}51}5253/* at this point: m = ocb->block_index (last block index), Offset_m = ocb->Offset_current */5455if (last_block_len>0) {56/* Offset_* = Offset_m xor L_* */57ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);5859/* Pad = ENCIPHER(K, Offset_*) */60if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {61goto LBL_ERR;62}6364/* C_* = P_* xor Pad[1..bitlen(P_*)] */65ocb3_int_xor_blocks(ct+full_blocks_len, pt+full_blocks_len, iPad, last_block_len);6667/* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */68ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);69for(x=last_block_len; x<ocb->block_len; x++) {70if (x == last_block_len)71ocb->checksum[x] ^= 0x80;72else73ocb->checksum[x] ^= 0x00;74}7576/* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */77/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */78for(x=0; x<ocb->block_len; x++) {79ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];80}81if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {82goto LBL_ERR;83}84}85else {86/* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */87/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */88for(x=0; x<ocb->block_len; x++) {89ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];90}91if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {92goto LBL_ERR;93}94}9596err = CRYPT_OK;9798LBL_ERR:99#ifdef LTC_CLEAN_STACK100zeromem(iOffset_star, MAXBLOCKSIZE);101zeromem(iPad, MAXBLOCKSIZE);102#endif103104return err;105}106107#endif108109110