// 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.
 */

/******************************************************************************
 * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
 * and should run on any conforming C implementation (C90 or later).
 *
 * This implementation supports any key length up to 128 bits (16 bytes) and
 * works in increments of 8-bit bytes.  Keys must be submitted as whole bytes
 * and shorter keys will be right-null-padded to 16 bytes.  Likewise, an iv
 * may be any length up to 8 bytes and will be padded out to 8 bytes.
 *
 * The eSTREAM submission was rather picky about the calling sequence of
 * ECRYPT_process_blocks() and ECRYPT_process_bytes().  That version allowed
 * calling ECRYPT_process_blocks() multiple times for a multiple of whole
 * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
 * were supported correctly.  This implementation handles the keystream
 * differently and rabbit_crypt() may be called as many times as desired,
 * crypting any number of bytes each time.
 *
 *   http://www.ecrypt.eu.org/stream/e2-rabbit.html
 *
 * NB: One of the test vectors distributed by the eSTREAM site in the file
 *     "rabbit_p3source.zip" is in error.  Referring to "test-vectors.txt"
 *     in that ZIP file, the 3rd line in "out1" should be
 *     "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
 *
 * Here is the original legal notice accompanying the Rabbit submission
 * to the EU eSTREAM competition.
 *---------------------------------------------------------------------------
 * Copyright (C) Cryptico A/S. All rights reserved.
 *
 * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
 *
 * This software is developed by Cryptico A/S and/or its suppliers.
 * All title and intellectual property rights in and to the software,
 * including but not limited to patent rights and copyrights, are owned
 * by Cryptico A/S and/or its suppliers.
 *
 * The software may be used solely for non-commercial purposes
 * without the prior written consent of Cryptico A/S. For further
 * information on licensing terms and conditions please contact
 * Cryptico A/S at info@cryptico.com
 *
 * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
 * are either trademarks or registered trademarks of Cryptico A/S.
 *
 * Cryptico A/S shall not in any way be liable for any use of this
 * software. The software is provided "as is" without any express or
 * implied warranty.
 *---------------------------------------------------------------------------
 * On October 6, 2008, Rabbit was "released into the public domain and
 * may be used freely for any purpose."
 *   http://www.ecrypt.eu.org/stream/rabbitpf.html
 *   https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
 ******************************************************************************/


#include "tomcrypt_private.h"

#ifdef LTC_RABBIT

/* local/private prototypes  (NB: rabbit_ctx and rabbit_state are different)  */
static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x);
static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance);
static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out);

/* -------------------------------------------------------------------------- */

/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
/* the upper 32 bits XOR the lower 32 bits */
static LTC_INLINE ulong32 _rabbit_g_func(ulong32 x)
{
   ulong32 a, b, h, l;

   /* Construct high and low argument for squaring */
   a = x &  0xFFFF;
   b = x >> 16;

   /* Calculate high and low result of squaring */
   h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
   l = x * x;

   /* Return high XOR low */
   return (ulong32)(h^l);
}

/* -------------------------------------------------------------------------- */

/* Calculate the next internal state */
static LTC_INLINE void _rabbit_next_state(rabbit_ctx *p_instance)
{
   ulong32 g[8], c_old[8], i;

   /* Save old counter values */
   for (i=0; i<8; i++) {
      c_old[i] = p_instance->c[i];
   }

   /* Calculate new counter values */
   p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
   p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
   p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
   p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
   p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
   p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
   p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
   p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
   p_instance->carry = (p_instance->c[7] < c_old[7]);

   /* Calculate the g-values */
   for (i=0;i<8;i++) {
      g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
   }

   /* Calculate new state values */
   p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
   p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
   p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
   p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
   p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
   p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
   p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
   p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
}

/* ------------------------------------------------------------------------- */

static LTC_INLINE void _rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
{
    ulong32 *ptr;

    /* Iterate the work context once */
    _rabbit_next_state(&(st->work_ctx));

    /* Generate 16 bytes of pseudo-random data */
    ptr = (ulong32*)&(st->work_ctx.x);
    STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
    STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
    STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
    STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
}

/* -------------------------------------------------------------------------- */

/* Key setup */
int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
{
   ulong32 k0, k1, k2, k3, i;
   unsigned char  tmpkey[16] = {0};

   LTC_ARGCHK(st != NULL);
   LTC_ARGCHK(key != NULL);
   LTC_ARGCHK(keylen <= 16);

   /* init state */
   XMEMSET(st, 0, sizeof(rabbit_state));

   /* pad key in tmpkey */
   XMEMCPY(tmpkey, key, keylen);

   /* Generate four subkeys */
   LOAD32L(k0, tmpkey+ 0);
   LOAD32L(k1, tmpkey+ 4);
   LOAD32L(k2, tmpkey+ 8);
   LOAD32L(k3, tmpkey+12);

#ifdef LTC_CLEAN_STACK
   /* done with tmpkey, wipe it */
   zeromem(tmpkey, sizeof(tmpkey));
#endif

   /* Generate initial state variables */
   st->master_ctx.x[0] = k0;
   st->master_ctx.x[2] = k1;
   st->master_ctx.x[4] = k2;
   st->master_ctx.x[6] = k3;
   st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
   st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
   st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
   st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);

   /* Generate initial counter values */
   st->master_ctx.c[0] = ROLc(k2, 16);
   st->master_ctx.c[2] = ROLc(k3, 16);
   st->master_ctx.c[4] = ROLc(k0, 16);
   st->master_ctx.c[6] = ROLc(k1, 16);
   st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
   st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
   st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
   st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);

   /* Clear carry bit */
   st->master_ctx.carry = 0;

   /* Iterate the master context four times */
   for (i=0; i<4; i++) {
      _rabbit_next_state(&(st->master_ctx));
   }

   /* Modify the counters */
   for (i=0; i<8; i++) {
      st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
   }

   /* Copy master instance to work instance */
   for (i=0; i<8; i++) {
      st->work_ctx.x[i] = st->master_ctx.x[i];
      st->work_ctx.c[i] = st->master_ctx.c[i];
   }
   st->work_ctx.carry = st->master_ctx.carry;
   /* ...and prepare block for crypt() */
   XMEMSET(&(st->block), 0, sizeof(st->block));
   st->unused = 0;

   return CRYPT_OK;
}

/* -------------------------------------------------------------------------- */

/* IV setup */
int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
{
   ulong32 i0, i1, i2, i3, i;
   unsigned char  tmpiv[8] = {0};

   LTC_ARGCHK(st != NULL);
   LTC_ARGCHK(iv != NULL || ivlen == 0);
   LTC_ARGCHK(ivlen <= 8);

   /* pad iv in tmpiv */
   if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);

   /* Generate four subvectors */
   LOAD32L(i0, tmpiv+0);
   LOAD32L(i2, tmpiv+4);
   i1 = (i0>>16) | (i2&0xFFFF0000);
   i3 = (i2<<16) | (i0&0x0000FFFF);

   /* Modify counter values */
   st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
   st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
   st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
   st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
   st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
   st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
   st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
   st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;

   /* Copy state variables */
   for (i=0; i<8; i++) {
      st->work_ctx.x[i] = st->master_ctx.x[i];
   }
   st->work_ctx.carry = st->master_ctx.carry;

   /* Iterate the work context four times */
   for (i=0; i<4; i++) {
      _rabbit_next_state(&(st->work_ctx));
   }

   /* reset keystream buffer and unused count */
   XMEMSET(&(st->block), 0, sizeof(st->block));
   st->unused = 0;

   return CRYPT_OK;
}

/* ------------------------------------------------------------------------- */

/* Crypt a chunk of any size (encrypt/decrypt) */
int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
{
   unsigned char buf[16];
   unsigned long i, j;

   if (inlen == 0) return CRYPT_OK; /* nothing to do */

   LTC_ARGCHK(st        != NULL);
   LTC_ARGCHK(in        != NULL);
   LTC_ARGCHK(out       != NULL);

   if (st->unused > 0) {
      j = MIN(st->unused, inlen);
      for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
      inlen -= j;
      if (inlen == 0) return CRYPT_OK;
      out += j;
      in  += j;
   }
   for (;;) {
     /* gen a block for buf */
     _rabbit_gen_1_block(st, buf);
     if (inlen <= 16) {
       /* XOR and send to out */
       for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
       st->unused = 16 - inlen;
       /* copy remainder to block */
       for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
       return CRYPT_OK;
     }
     /* XOR entire buf and send to out */
     for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
     inlen -= 16;
     out += 16;
     in  += 16;
   }
}

/* ------------------------------------------------------------------------- */

int rabbit_keystream(rabbit_state *st, unsigned char *out, unsigned long outlen)
{
   if (outlen == 0) return CRYPT_OK; /* nothing to do */

   LTC_ARGCHK(out != NULL);

   XMEMSET(out, 0, outlen);
   return rabbit_crypt(st, out, outlen, out);
}

/* -------------------------------------------------------------------------- */

int rabbit_done(rabbit_state *st)
{
   LTC_ARGCHK(st != NULL);

   zeromem(st, sizeof(rabbit_state));
   return CRYPT_OK;
}

/* -------------------------------------------------------------------------- */

int rabbit_test(void)
{
#ifndef LTC_TEST
   return CRYPT_NOP;
#else
   rabbit_state st;
   int err;
   unsigned char out[1000] = { 0 };
   {
      /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
         http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
      */

      /* --- Test 1 (generate whole blocks) --------------------------------- */

      {
         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
         char pt[64]        = { 0 };
         unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
                                0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
                                0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
                                0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
                                0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
                                0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
                                0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
                                0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
         unsigned long ptlen = sizeof(pt);

         /* crypt 64 nulls */
         if ((err = rabbit_setup(&st, k, sizeof(k)))                   != CRYPT_OK) return err;
         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                 != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1))   return CRYPT_FAIL_TESTVECTOR;
      }

      /* --- Test 2 (generate unusual number of bytes each time) ------------ */

      {
         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
         char          pt[39] = { 0 };
         unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA,   0x96, 0xAF, 0xF6, 0xCA,
                                0xCF, 0x2A, 0x45, 0x9A,   0x10, 0x2A, 0x7F, 0x78,
                                0xCA, 0x98, 0x5C, 0xF8,   0xFD, 0xD1, 0x47, 0x40,
                                0x18, 0x75, 0x8E, 0x36,   0xAE, 0x99, 0x23, 0xF5,
                                0x19, 0xD1, 0x3D, 0x71,   0x8D, 0xAF, 0x8D };
         unsigned long ptlen = sizeof(pt);

         /* crypt piece by piece (hit at least one 16-byte boundary) */
         if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 11, out +  5)) != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30,  2, out + 30)) != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32,  7, out + 32)) != CRYPT_OK) return err;
         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1))   return CRYPT_FAIL_TESTVECTOR;
      }

      /* --- Test 3 (use non-null data) ------------------------------------- */

      {
         unsigned char k[]  = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
         unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
         char          pt[] = "Kilroy was here, there, and everywhere!";
         unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8,   0xf9, 0xd6, 0xd6, 0xbd,
                                0xae, 0x59, 0x65, 0xf2,   0x75, 0x58, 0x1a, 0x54,
                                0xea, 0xec, 0x34, 0x9d,   0x8f, 0xb4, 0x6b, 0x60,
                                0x79, 0x1b, 0xea, 0x16,   0xcb, 0xef, 0x46, 0x87,
                                0x60, 0xa6, 0x55, 0x14,   0xff, 0xca, 0xac };
         unsigned long ptlen = strlen(pt);
         unsigned char out2[1000] = { 0 };
         unsigned char nulls[1000] = { 0 };

         /* crypt piece by piece */
         if ((err = rabbit_setup(&st, k, sizeof(k)))                          != CRYPT_OK) return err;
         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt,       5, out))      != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt +  5, 29, out +  5)) != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34,  5, out + 34)) != CRYPT_OK) return err;
         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1))   return CRYPT_FAIL_TESTVECTOR;

      /* --- Test 4 (crypt in a single call) ------------------------------------ */

         if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv),
                                   (unsigned char*)pt, sizeof(pt), out))      != CRYPT_OK) return err;
         if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1))   return CRYPT_FAIL_TESTVECTOR;
         /* use 'out' (ciphertext) in the next decryption test */

      /* --- Test 5 (decrypt ciphertext) ------------------------------------ */

         /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
         if ((err = rabbit_setiv(&st, iv, sizeof(iv)))                        != CRYPT_OK) return err;
         if ((err = rabbit_crypt(&st, out, ptlen, out2))                      != CRYPT_OK) return err;
         if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1))  return CRYPT_FAIL_TESTVECTOR;

      /* --- Test 6 (wipe state, incl key) ---------------------------------- */

         if ((err = rabbit_done(&st))                      != CRYPT_OK) return err;
         if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1))  return CRYPT_FAIL_TESTVECTOR;

      }

      return CRYPT_OK;
   }
#endif
}

/* -------------------------------------------------------------------------- */

#endif

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