// SPDX-License-Identifier: BSD-2-Clause
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
 *
 * LibTomCrypt is a library that provides various cryptographic
 * algorithms in a highly modular and flexible manner.
 *
 * The library is free for all purposes without any express
 * guarantee it works.
 */

/**
   @file ocb3_init.c
   OCB implementation, initialize state, by Tom St Denis
*/
#include "tomcrypt_private.h"

#ifdef LTC_OCB3_MODE

static void _ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen)
{
   int x, y, bottom;
   int idx, shift;
   unsigned char iNonce[MAXBLOCKSIZE];
   unsigned char iKtop[MAXBLOCKSIZE];
   unsigned char iStretch[MAXBLOCKSIZE+8];

   /* Nonce = zeros(127-bitlen(N)) || 1 || N          */
   zeromem(iNonce, sizeof(iNonce));
   for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) {
     iNonce[x] = nonce[noncelen-y-1];
   }
   iNonce[x] = 0x01;
   iNonce[0] |= ((taglen*8) % 128) << 1;

   /* bottom = str2num(Nonce[123..128])               */
   bottom = iNonce[ocb->block_len-1] & 0x3F;

   /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6))   */
   iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0;
   if ((cipher_descriptor[ocb->cipher]->ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) {
      zeromem(ocb->Offset_current, ocb->block_len);
      return;
   }

   /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
   for (x = 0; x < ocb->block_len; x++) {
     iStretch[x] = iKtop[x];
   }
   for (y = 0; y < 8; y++) {
     iStretch[x+y] = iKtop[y] ^ iKtop[y+1];
   }

   /* Offset_0 = Stretch[1+bottom..128+bottom]        */
   idx = bottom / 8;
   shift = (bottom % 8);
   for (x = 0; x < ocb->block_len; x++) {
      ocb->Offset_current[x] = iStretch[idx+x] << shift;
      if (shift > 0) {
        ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift);
      }
   }
}

static const struct {
    int           len;
    unsigned char poly_mul[MAXBLOCKSIZE];
} polys[] = {
{
    8,
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
}, {
    16,
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
}
};

/**
   Initialize an OCB context
   @param ocb       [out] The destination of the OCB state
   @param cipher    The index of the desired cipher
   @param key       The secret key
   @param keylen    The length of the secret key (octets)
   @param nonce     The session nonce
   @param noncelen  The length of the session nonce (octets, up to 15)
   @param taglen    The length of the tag (octets, up to 16)
   @return CRYPT_OK if successful
*/
int ocb3_init(ocb3_state *ocb, int cipher,
             const unsigned char *key, unsigned long keylen,
             const unsigned char *nonce, unsigned long noncelen,
             unsigned long taglen)
{
   int poly, x, y, m, err;
   unsigned char *previous, *current;

   LTC_ARGCHK(ocb   != NULL);
   LTC_ARGCHK(key   != NULL);
   LTC_ARGCHK(nonce != NULL);

   /* valid cipher? */
   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
      return err;
   }
   ocb->cipher = cipher;

   /* Valid Nonce?
    * As of RFC7253: "string of no more than 120 bits" */
   if (noncelen > (120/8)) {
      return CRYPT_INVALID_ARG;
   }

   /* The blockcipher must have a 128-bit blocksize */
   if (cipher_descriptor[cipher]->block_length != 16) {
      return CRYPT_INVALID_ARG;
   }

   /* The TAGLEN may be any value up to 128 (bits) */
   if (taglen > 16) {
      return CRYPT_INVALID_ARG;
   }
   ocb->tag_len = taglen;

   /* determine which polys to use */
   ocb->block_len = cipher_descriptor[cipher]->block_length;
   x = (int)(sizeof(polys)/sizeof(polys[0]));
   for (poly = 0; poly < x; poly++) {
       if (polys[poly].len == ocb->block_len) {
          break;
       }
   }
   if (poly == x) {
      return CRYPT_INVALID_ARG; /* block_len not found in polys */
   }
   if (polys[poly].len != ocb->block_len) {
      return CRYPT_INVALID_ARG;
   }

   /* schedule the key */
   if ((err = cipher_descriptor[cipher]->setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
      return err;
   }

   /* L_* = ENCIPHER(K, zeros(128)) */
   zeromem(ocb->L_star, ocb->block_len);
   if ((err = cipher_descriptor[cipher]->ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) {
      return err;
   }

   /* compute L_$, L_0, L_1, ... */
   for (x = -1; x < 32; x++) {
      if (x == -1) {                /* gonna compute: L_$ = double(L_*) */
         current  = ocb->L_dollar;
         previous = ocb->L_star;
      }
      else if (x == 0) {            /* gonna compute: L_0 = double(L_$) */
         current  = ocb->L_[0];
         previous = ocb->L_dollar;
      }
      else {                        /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */
         current  = ocb->L_[x];
         previous = ocb->L_[x-1];
      }
      m = previous[0] >> 7;
      for (y = 0; y < ocb->block_len-1; y++) {
         current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255;
      }
      current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255;
      if (m == 1) {
         /* current[] = current[] XOR polys[poly].poly_mul[]*/
         ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len);
      }
   }

   /* initialize ocb->Offset_current = Offset_0 */
   _ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen);

   /* initialize checksum to all zeros */
   zeromem(ocb->checksum, ocb->block_len);

   /* set block index */
   ocb->block_index = 1;

   /* initialize AAD related stuff */
   ocb->ablock_index = 1;
   ocb->adata_buffer_bytes = 0;
   zeromem(ocb->aOffset_current, ocb->block_len);
   zeromem(ocb->aSum_current, ocb->block_len);

   return CRYPT_OK;
}

#endif

/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */
