Path: blob/master/libs/tomcrypt/src/encauth/ocb/ocb_init.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 ocb_init.c11OCB implementation, initialize state, by Tom St Denis12*/13#include "tomcrypt.h"1415#ifdef LTC_OCB_MODE1617static const struct {18int len;19unsigned char poly_div[MAXBLOCKSIZE],20poly_mul[MAXBLOCKSIZE];21} polys[] = {22{238,24{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },25{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }26}, {2716,28{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },30{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }32}33};3435/**36Initialize an OCB context.37@param ocb [out] The destination of the OCB state38@param cipher The index of the desired cipher39@param key The secret key40@param keylen The length of the secret key (octets)41@param nonce The session nonce (length of the block size of the cipher)42@return CRYPT_OK if successful43*/44int ocb_init(ocb_state *ocb, int cipher,45const unsigned char *key, unsigned long keylen, const unsigned char *nonce)46{47int poly, x, y, m, err;4849LTC_ARGCHK(ocb != NULL);50LTC_ARGCHK(key != NULL);51LTC_ARGCHK(nonce != NULL);5253/* valid cipher? */54if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {55return err;56}5758/* determine which polys to use */59ocb->block_len = cipher_descriptor[cipher].block_length;60x = (int)(sizeof(polys)/sizeof(polys[0]));61for (poly = 0; poly < x; poly++) {62if (polys[poly].len == ocb->block_len) {63break;64}65}66if (poly == x) {67return CRYPT_INVALID_ARG; /* block_len not found in polys */68}69if (polys[poly].len != ocb->block_len) {70return CRYPT_INVALID_ARG;71}7273/* schedule the key */74if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {75return err;76}7778/* find L = E[0] */79zeromem(ocb->L, ocb->block_len);80if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {81return err;82}8384/* find R = E[N xor L] */85for (x = 0; x < ocb->block_len; x++) {86ocb->R[x] = ocb->L[x] ^ nonce[x];87}88if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {89return err;90}9192/* find Ls[i] = L << i for i == 0..31 */93XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);94for (x = 1; x < 32; x++) {95m = ocb->Ls[x-1][0] >> 7;96for (y = 0; y < ocb->block_len-1; y++) {97ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255;98}99ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255;100101if (m == 1) {102for (y = 0; y < ocb->block_len; y++) {103ocb->Ls[x][y] ^= polys[poly].poly_mul[y];104}105}106}107108/* find Lr = L / x */109m = ocb->L[ocb->block_len-1] & 1;110111/* shift right */112for (x = ocb->block_len - 1; x > 0; x--) {113ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255;114}115ocb->Lr[0] = ocb->L[0] >> 1;116117if (m == 1) {118for (x = 0; x < ocb->block_len; x++) {119ocb->Lr[x] ^= polys[poly].poly_div[x];120}121}122123/* set Li, checksum */124zeromem(ocb->Li, ocb->block_len);125zeromem(ocb->checksum, ocb->block_len);126127/* set other params */128ocb->block_index = 1;129ocb->cipher = cipher;130131return CRYPT_OK;132}133134#endif135136137