예제 #1
0
파일: s128fast.c 프로젝트: bukka/libmcrypt
/* Having accumulated a MAC, finish processing and return it */
void
s128_finish(s128_ctx *c, UCHAR *buf, int nbytes)
{
    UCHAR       *endbuf;
    WORD	t = 0;

    if ((nbytes & 3) != 0)
	abort();
    /* perturb the state to mark end of input -- sort of like adding more key */
    ADDKEY(INITKONST);
    cycle(c->R);
    XORNL(nltap(c));
    s128_diffuse(c);
    /* don't bother optimising this loop, because it's a state
     * of delusion to generate more than N words of MAC.
     */
    endbuf = &buf[nbytes];
    while (buf < endbuf)
    {
	cycle(c->R);
	t = nltap(c);
	WORD2BYTE(t, buf);
	buf += 4;
    }
}
예제 #2
0
/**
  Add entropy to the PRNG state
  @param in       The data to add
  @param inlen    Length of the data to add
  @param prng     PRNG state to update
  @return CRYPT_OK if successful
*/  
int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
{
    struct sober128_prng *c;
    ulong32               i, k;

    LTC_ARGCHK(in != NULL);
    LTC_ARGCHK(prng != NULL);
    c = &(prng->sober128);

    if (c->flag == 1) {
       /* this is the first call to the add_entropy so this input is the key */
       /* inlen must be multiple of 4 bytes */
       if ((inlen & 3) != 0) {
          return CRYPT_INVALID_KEYSIZE;
       }
    
       for (i = 0; i < inlen; i += 4) {
           k = BYTE2WORD((unsigned char *)&in[i]);
          ADDKEY(k);
          cycle(c->R);
          XORNL(nltap(c));
       }

       /* also fold in the length of the key */
       ADDKEY(inlen);

       /* now diffuse */
       s128_diffuse(c);

       s128_genkonst(c);
       s128_savestate(c);
       c->nbuf = 0;
       c->flag = 0;       
       c->set  = 1;
    } else {
       /* ok we are adding an IV then... */
       s128_reloadstate(c);

       /* inlen must be multiple of 4 bytes */
       if ((inlen & 3) != 0) {
          return CRYPT_INVALID_KEYSIZE;
       }
    
       for (i = 0; i < inlen; i += 4) {
           k = BYTE2WORD((unsigned char *)&in[i]);
          ADDKEY(k);
          cycle(c->R);
          XORNL(nltap(c));
       }

       /* also fold in the length of the key */
       ADDKEY(inlen);

       /* now diffuse */
       s128_diffuse(c);
       c->nbuf = 0;
    }

    return CRYPT_OK;
}
예제 #3
0
unsigned long sober128_read(unsigned char *buf, unsigned long nbytes, sober128_prng *c)
{
   ulong32               t, tlen;

   tlen = nbytes;

   /* handle any previously buffered bytes */
   while (c->nbuf != 0 && nbytes != 0) {
      *buf++ ^= c->sbuf & 0xFF;
       c->sbuf >>= 8;
       c->nbuf -= 8;
       --nbytes;
   }

#ifndef SMALL_CODE
    /* do lots at a time, if there's enough to do */
    while (nbytes >= N*4) {
      SROUND(0);
      SROUND(1);
      SROUND(2);
      SROUND(3);
      SROUND(4);
      SROUND(5);
      SROUND(6);
      SROUND(7);
      SROUND(8);
      SROUND(9);
      SROUND(10);
      SROUND(11);
      SROUND(12);
      SROUND(13);
      SROUND(14);
      SROUND(15);
      SROUND(16);
      buf    += 4*N;
      nbytes -= 4*N;
    }
#endif

    /* do small or odd size buffers the slow way */
    while (4 <= nbytes) {
      cycle(c->R);
      t = nltap(c);
      XORWORD(t, buf);
      buf    += 4;
      nbytes -= 4;
    }

    /* handle any trailing bytes */
    if (nbytes != 0) {
      cycle(c->R);
      c->sbuf = nltap(c);
      c->nbuf = 32;
      while (c->nbuf != 0 && nbytes != 0) {
        *buf++ ^= c->sbuf & 0xFF;
        c->sbuf >>= 8;
        c->nbuf -= 8;
        --nbytes;
      }
    }
예제 #4
0
int sober128_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
{
    struct sober128_prng *c;
    ulong32               i, k;

    c = &(prng->sober128);

    if (c->flag == 1) {
       /* this is the first call to the add_entropy so this input is the key */
       /* len must be multiple of 4 bytes */
       assert ((len & 3) == 0);

       for (i = 0; i < len; i += 4) {
           k = BYTE2WORD(&buf[i]);
          ADDKEY(k);
          cycle(c->R);
          XORNL(nltap(c));
       }

       /* also fold in the length of the key */
       ADDKEY(len);

       /* now diffuse */
       s128_diffuse(c);

       s128_genkonst(c);
       s128_savestate(c);
       c->nbuf = 0;
       c->flag = 0;
       c->set  = 1;
    } else {
       /* ok we are adding an IV then... */
       s128_reloadstate(c);

       /* len must be multiple of 4 bytes */
       assert ((len & 3) == 0);

       for (i = 0; i < len; i += 4) {
           k = BYTE2WORD(&buf[i]);
          ADDKEY(k);
          cycle(c->R);
          XORNL(nltap(c));
       }

       /* also fold in the length of the key */
       ADDKEY(len);

       /* now diffuse */
       s128_diffuse(c);
       c->nbuf = 0;
    }

    return CRYPT_OK;
}
예제 #5
0
/**
  Set IV to the Sober128 state
  @param c       The Sober12820 state
  @param iv      The IV data to add
  @param ivlen   The length of the IV (must be 12)
  @return CRYPT_OK on success
 */
int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen)
{
   ulong32 i, k;

   LTC_ARGCHK(c  != NULL);
   LTC_ARGCHK(iv != NULL);
   LTC_ARGCHK(ivlen > 0);

   /* ok we are adding an IV then... */
   s128_reloadstate(c);

   /* ivlen must be multiple of 4 bytes */
   if ((ivlen & 3) != 0) {
      return CRYPT_INVALID_KEYSIZE;
   }

   for (i = 0; i < ivlen; i += 4) {
      k = BYTE2WORD((unsigned char *)&iv[i]);
      ADDKEY(k);
      cycle(c->R);
      XORNL(nltap(c));
   }

   /* also fold in the length of the key */
   ADDKEY(ivlen);

   /* now diffuse */
   s128_diffuse(c);
   c->nbuf = 0;

   return CRYPT_OK;
}
예제 #6
0
/* Initialise "konst"
 */
static void s128_genkonst(struct sober128_prng *c)
{
    ulong32 newkonst;

    do {
       cycle(c->R);
       newkonst = nltap(c);
    } while ((newkonst & 0xFF000000) == 0);
    c->konst = newkonst;
}
예제 #7
0
파일: s128fast.c 프로젝트: bukka/libmcrypt
/* Initialise "konst"
 */
static void
s128_genkonst(s128_ctx *c)
{
    WORD	newkonst;

    do {
	cycle(c->R);
	newkonst = nltap(c);
    } while ((newkonst & 0xFF000000) == 0);
    c->konst = newkonst;
}
예제 #8
0
파일: s128fast.c 프로젝트: bukka/libmcrypt
void
s128_decrypt(s128_ctx *c, UCHAR *buf, int nbytes)
{
    UCHAR       *endbuf;
    WORD	t = 0;

    if ((nbytes & 3) != 0)
	abort();
    endbuf = &buf[nbytes];
    /* do small or odd size buffers the slow way, at least at first */
    while ((nbytes % (N*4)) != 0) {
	cycle(c->R);
	t = nltap(c);
	t ^= BYTE2WORD(buf);
	macfunc(c, t);
	WORD2BYTE(t, buf);
	nbytes -= 4;
	buf += 4;
    }
    /* now do lots at a time, if there's any left */
    while (buf < endbuf)
    {
	DROUND(0);
	DROUND(1);
	DROUND(2);
	DROUND(3);
	DROUND(4);
	DROUND(5);
	DROUND(6);
	DROUND(7);
	DROUND(8);
	DROUND(9);
	DROUND(10);
	DROUND(11);
	DROUND(12);
	DROUND(13);
	DROUND(14);
	DROUND(15);
	DROUND(16);
	buf += 4*17;
    }
}
예제 #9
0
/**
   Initialize an Sober128 context (only the key)
   @param c         [out] The destination of the Sober128 state
   @param key       The secret key
   @param keylen    The length of the secret key (octets)
   @return CRYPT_OK if successful
*/
int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen)
{
   ulong32 i, k;

   LTC_ARGCHK(c   != NULL);
   LTC_ARGCHK(key != NULL);
   LTC_ARGCHK(keylen > 0);

   /* keylen must be multiple of 4 bytes */
   if ((keylen & 3) != 0) {
      return CRYPT_INVALID_KEYSIZE;
   }

   /* Register initialised to Fibonacci numbers */
   c->R[0] = 1;
   c->R[1] = 1;
   for (i = 2; i < N; ++i) {
      c->R[i] = c->R[i-1] + c->R[i-2];
   }
   c->konst = INITKONST;

   for (i = 0; i < keylen; i += 4) {
      k = BYTE2WORD((unsigned char *)&key[i]);
      ADDKEY(k);
      cycle(c->R);
      XORNL(nltap(c));
   }

   /* also fold in the length of the key */
   ADDKEY(keylen);

   /* now diffuse */
   s128_diffuse(c);
   s128_genkonst(c);
   s128_savestate(c);
   c->nbuf = 0;

   return CRYPT_OK;
}
예제 #10
0
파일: s128fast.c 프로젝트: bukka/libmcrypt
static void
s128_loadkey(s128_ctx *c, UCHAR key[], int keylen)
{
    int		i;
    WORD	k;

    /* start folding in key, reject odd sized keys */
    if ((keylen & 3) != 0)
	abort();
    for (i = 0; i < keylen; i += 4)
    {
	k = BYTE2WORD(&key[i]);
	ADDKEY(k);
        cycle(c->R);
	XORNL(nltap(c));
    }

    /* also fold in the length of the key */
    ADDKEY(keylen);

    /* now diffuse */
    s128_diffuse(c);
}
예제 #11
0
/**
  Read from the PRNG
  @param out      Destination
  @param outlen   Length of output
  @param prng     The active PRNG to read from
  @return Number of octets read
*/  
unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng)
{
   struct sober128_prng *c;
   ulong32               t, tlen;

   LTC_ARGCHK(out  != NULL);
   LTC_ARGCHK(prng != NULL);

#ifdef LTC_VALGRIND
   zeromem(out, outlen);
#endif

   c = &(prng->sober128);
   t = 0;
   tlen = outlen;
   
   /* handle any previously buffered bytes */
   while (c->nbuf != 0 && outlen != 0) {
      *out++ ^= c->sbuf & 0xFF;
       c->sbuf >>= 8;
       c->nbuf -= 8;
       --outlen;
   }

#ifndef LTC_SMALL_CODE
    /* do lots at a time, if there's enough to do */
    while (outlen >= N*4) {
      SROUND(0);
      SROUND(1);
      SROUND(2);
      SROUND(3);
      SROUND(4);
      SROUND(5);
      SROUND(6);
      SROUND(7);
      SROUND(8);
      SROUND(9);
      SROUND(10);
      SROUND(11);
      SROUND(12);
      SROUND(13);
      SROUND(14);
      SROUND(15);
      SROUND(16);
      out    += 4*N;
      outlen -= 4*N;
    }
#endif

    /* do small or odd size buffers the slow way */
    while (4 <= outlen) {
      cycle(c->R);
      t = nltap(c);
      XORWORD(t, out);
      out    += 4;
      outlen -= 4;
    }

    /* handle any trailing bytes */
    if (outlen != 0) {
      cycle(c->R);
      c->sbuf = nltap(c);
      c->nbuf = 32;
      while (c->nbuf != 0 && outlen != 0) {
          *out++ ^= c->sbuf & 0xFF;
          c->sbuf >>= 8;
          c->nbuf -= 8;
          --outlen;
      }
    }
예제 #12
0
/**
   Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128
   @param c       The Sober128 state
   @param in      The plaintext (or ciphertext)
   @param inlen   The length of the input (octets)
   @param out     [out] The ciphertext (or plaintext), length inlen
   @return CRYPT_OK if successful
*/
int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out)
{
   ulong32 t;

   if (inlen == 0) return CRYPT_OK; /* nothing to do */
   LTC_ARGCHK(out != NULL);
   LTC_ARGCHK(c   != NULL);

   /* handle any previously buffered bytes */
   while (c->nbuf != 0 && inlen != 0) {
      *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF);
      c->sbuf >>= 8;
      c->nbuf -= 8;
      --inlen;
   }

#ifndef LTC_SMALL_CODE
   /* do lots at a time, if there's enough to do */
   while (inlen >= N*4) {
      SROUND(0);
      SROUND(1);
      SROUND(2);
      SROUND(3);
      SROUND(4);
      SROUND(5);
      SROUND(6);
      SROUND(7);
      SROUND(8);
      SROUND(9);
      SROUND(10);
      SROUND(11);
      SROUND(12);
      SROUND(13);
      SROUND(14);
      SROUND(15);
      SROUND(16);
      out    += 4*N;
      in     += 4*N;
      inlen  -= 4*N;
   }
#endif

   /* do small or odd size buffers the slow way */
   while (4 <= inlen) {
      cycle(c->R);
      t = nltap(c);
      XORWORD(t, in, out);
      out    += 4;
      in     += 4;
      inlen  -= 4;
   }

   /* handle any trailing bytes */
   if (inlen != 0) {
      cycle(c->R);
      c->sbuf = nltap(c);
      c->nbuf = 32;
      while (c->nbuf != 0 && inlen != 0) {
          *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF);
          c->sbuf >>= 8;
          c->nbuf -= 8;
          --inlen;
      }
   }