forked from wolfSSL/wolfssl
prune ctaocrypt, alter cyassl headers and catch wolfssl rsa header
This commit is contained in:
@@ -1,179 +0,0 @@
|
||||
/* arc4.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifndef NO_RC4
|
||||
|
||||
#include <cyassl/ctaocrypt/arc4.h>
|
||||
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length);
|
||||
static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in,
|
||||
word32 length);
|
||||
#endif
|
||||
|
||||
|
||||
void Arc4SetKey(Arc4* arc4, const byte* key, word32 length)
|
||||
{
|
||||
word32 i;
|
||||
word32 keyIndex = 0, stateIndex = 0;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC)
|
||||
return Arc4CaviumSetKey(arc4, key, length);
|
||||
#endif
|
||||
|
||||
arc4->x = 1;
|
||||
arc4->y = 0;
|
||||
|
||||
for (i = 0; i < ARC4_STATE_SIZE; i++)
|
||||
arc4->state[i] = (byte)i;
|
||||
|
||||
for (i = 0; i < ARC4_STATE_SIZE; i++) {
|
||||
word32 a = arc4->state[i];
|
||||
stateIndex += key[keyIndex] + a;
|
||||
stateIndex &= 0xFF;
|
||||
arc4->state[i] = arc4->state[stateIndex];
|
||||
arc4->state[stateIndex] = (byte)a;
|
||||
|
||||
if (++keyIndex >= length)
|
||||
keyIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static INLINE byte MakeByte(word32* x, word32* y, byte* s)
|
||||
{
|
||||
word32 a = s[*x], b;
|
||||
*y = (*y+a) & 0xff;
|
||||
|
||||
b = s[*y];
|
||||
s[*x] = (byte)b;
|
||||
s[*y] = (byte)a;
|
||||
*x = (*x+1) & 0xff;
|
||||
|
||||
return s[(a+b) & 0xff];
|
||||
}
|
||||
|
||||
|
||||
void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)
|
||||
{
|
||||
word32 x;
|
||||
word32 y;
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC)
|
||||
return Arc4CaviumProcess(arc4, out, in, length);
|
||||
#endif
|
||||
|
||||
x = arc4->x;
|
||||
y = arc4->y;
|
||||
|
||||
while(length--)
|
||||
*out++ = *in++ ^ MakeByte(&x, &y, arc4->state);
|
||||
|
||||
arc4->x = (byte)x;
|
||||
arc4->y = (byte)y;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CAVIUM
|
||||
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#include "cavium_common.h"
|
||||
|
||||
/* Initiliaze Arc4 for use with Nitrox device */
|
||||
int Arc4InitCavium(Arc4* arc4, int devId)
|
||||
{
|
||||
if (arc4 == NULL)
|
||||
return -1;
|
||||
|
||||
if (CspAllocContext(CONTEXT_SSL, &arc4->contextHandle, devId) != 0)
|
||||
return -1;
|
||||
|
||||
arc4->devId = devId;
|
||||
arc4->magic = CYASSL_ARC4_CAVIUM_MAGIC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Free Arc4 from use with Nitrox device */
|
||||
void Arc4FreeCavium(Arc4* arc4)
|
||||
{
|
||||
if (arc4 == NULL)
|
||||
return;
|
||||
|
||||
if (arc4->magic != CYASSL_ARC4_CAVIUM_MAGIC)
|
||||
return;
|
||||
|
||||
CspFreeContext(CONTEXT_SSL, arc4->contextHandle, arc4->devId);
|
||||
arc4->magic = 0;
|
||||
}
|
||||
|
||||
|
||||
static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length)
|
||||
{
|
||||
word32 requestId;
|
||||
|
||||
if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->contextHandle, length,
|
||||
(byte*)key, &requestId, arc4->devId) != 0) {
|
||||
CYASSL_MSG("Bad Cavium Arc4 Init");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in,
|
||||
word32 length)
|
||||
{
|
||||
cyassl_word offset = 0;
|
||||
word32 requestId;
|
||||
|
||||
while (length > CYASSL_MAX_16BIT) {
|
||||
word16 slen = (word16)CYASSL_MAX_16BIT;
|
||||
if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE,
|
||||
slen, (byte*)in + offset, out + offset, &requestId,
|
||||
arc4->devId) != 0) {
|
||||
CYASSL_MSG("Bad Cavium Arc4 Encrypt");
|
||||
}
|
||||
length -= CYASSL_MAX_16BIT;
|
||||
offset += CYASSL_MAX_16BIT;
|
||||
}
|
||||
if (length) {
|
||||
word16 slen = (word16)length;
|
||||
if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE,
|
||||
slen, (byte*)in + offset, out + offset, &requestId,
|
||||
arc4->devId) != 0) {
|
||||
CYASSL_MSG("Bad Cavium Arc4 Encrypt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_CAVIUM */
|
||||
|
||||
#endif /* NO_ARC4 */
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,250 +0,0 @@
|
||||
/* chacha.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* based from
|
||||
* chacha-ref.c version 20080118
|
||||
* D. J. Bernstein
|
||||
* Public domain.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
|
||||
#include <cyassl/ctaocrypt/chacha.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
#define LITTLE32(x) ByteReverseWord32(x)
|
||||
#else
|
||||
#define LITTLE32(x) (x)
|
||||
#endif
|
||||
|
||||
/* Number of rounds */
|
||||
#define ROUNDS 20
|
||||
|
||||
#define U32C(v) (v##U)
|
||||
#define U32V(v) ((word32)(v) & U32C(0xFFFFFFFF))
|
||||
#define U8TO32_LITTLE(p) LITTLE32(((word32*)(p))[0])
|
||||
|
||||
#define ROTATE(v,c) rotlFixed(v, c)
|
||||
#define XOR(v,w) ((v) ^ (w))
|
||||
#define PLUS(v,w) (U32V((v) + (w)))
|
||||
#define PLUSONE(v) (PLUS((v),1))
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \
|
||||
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \
|
||||
x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \
|
||||
x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7);
|
||||
|
||||
|
||||
/**
|
||||
* Set up iv(nonce). Earlier versions used 64 bits instead of 96, this version
|
||||
* uses the typical AEAD 96 bit nonce and can do record sizes of 256 GB.
|
||||
*/
|
||||
int Chacha_SetIV(ChaCha* ctx, const byte* inIv, word32 counter)
|
||||
{
|
||||
word32 temp[3]; /* used for alignment of memory */
|
||||
XMEMSET(temp, 0, 12);
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 i;
|
||||
printf("NONCE : ");
|
||||
for (i = 0; i < 12; i++) {
|
||||
printf("%02x", inIv[i]);
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
XMEMCPY(temp, inIv, 12);
|
||||
|
||||
ctx->X[12] = counter; /* block counter */
|
||||
ctx->X[13] = temp[0]; /* fixed variable from nonce */
|
||||
ctx->X[14] = temp[1]; /* counter from nonce */
|
||||
ctx->X[15] = temp[2]; /* counter from nonce */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* "expand 32-byte k" as unsigned 32 byte */
|
||||
static const word32 sigma[4] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};
|
||||
/* "expand 16-byte k" as unsigned 16 byte */
|
||||
static const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574};
|
||||
|
||||
/**
|
||||
* Key setup. 8 word iv (nonce)
|
||||
*/
|
||||
int Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)
|
||||
{
|
||||
const word32* constants;
|
||||
const byte* k;
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef XSTREAM_ALIGN
|
||||
word32 alignKey[keySz / 4];
|
||||
if ((cyassl_word)key % 4) {
|
||||
CYASSL_MSG("ChachaSetKey unaligned key");
|
||||
XMEMCPY(alignKey, key, sizeof(alignKey));
|
||||
k = (byte*)alignKey;
|
||||
}
|
||||
else {
|
||||
k = key;
|
||||
}
|
||||
#else
|
||||
k = key;
|
||||
#endif /* XSTREAM_ALIGN */
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 i;
|
||||
printf("ChaCha key used :\n");
|
||||
for (i = 0; i < keySz; i++) {
|
||||
printf("%02x", key[i]);
|
||||
if ((i + 1) % 8 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
|
||||
ctx->X[4] = U8TO32_LITTLE(k + 0);
|
||||
ctx->X[5] = U8TO32_LITTLE(k + 4);
|
||||
ctx->X[6] = U8TO32_LITTLE(k + 8);
|
||||
ctx->X[7] = U8TO32_LITTLE(k + 12);
|
||||
if (keySz == 32) {
|
||||
k += 16;
|
||||
constants = sigma;
|
||||
}
|
||||
else {
|
||||
/* key size of 128 */
|
||||
if (keySz != 16)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
constants = tau;
|
||||
}
|
||||
ctx->X[ 8] = U8TO32_LITTLE(k + 0);
|
||||
ctx->X[ 9] = U8TO32_LITTLE(k + 4);
|
||||
ctx->X[10] = U8TO32_LITTLE(k + 8);
|
||||
ctx->X[11] = U8TO32_LITTLE(k + 12);
|
||||
ctx->X[ 0] = U8TO32_LITTLE(constants + 0);
|
||||
ctx->X[ 1] = U8TO32_LITTLE(constants + 1);
|
||||
ctx->X[ 2] = U8TO32_LITTLE(constants + 2);
|
||||
ctx->X[ 3] = U8TO32_LITTLE(constants + 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts word into bytes with rotations having been done.
|
||||
*/
|
||||
static INLINE void Chacha_wordtobyte(word32 output[16], const word32 input[16])
|
||||
{
|
||||
word32 x[16];
|
||||
word32 i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
x[i] = input[i];
|
||||
}
|
||||
|
||||
for (i = (ROUNDS); i > 0; i -= 2) {
|
||||
QUARTERROUND(0, 4, 8, 12)
|
||||
QUARTERROUND(1, 5, 9, 13)
|
||||
QUARTERROUND(2, 6, 10, 14)
|
||||
QUARTERROUND(3, 7, 11, 15)
|
||||
QUARTERROUND(0, 5, 10, 15)
|
||||
QUARTERROUND(1, 6, 11, 12)
|
||||
QUARTERROUND(2, 7, 8, 13)
|
||||
QUARTERROUND(3, 4, 9, 14)
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
x[i] = PLUS(x[i], input[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
output[i] = LITTLE32(x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a stream of bytes
|
||||
*/
|
||||
static void Chacha_encrypt_bytes(ChaCha* ctx, const byte* m, byte* c,
|
||||
word32 bytes)
|
||||
{
|
||||
byte* output;
|
||||
word32 temp[16]; /* used to make sure aligned */
|
||||
word32 i;
|
||||
|
||||
output = (byte*)temp;
|
||||
|
||||
if (!bytes) return;
|
||||
for (;;) {
|
||||
Chacha_wordtobyte(temp, ctx->X);
|
||||
ctx->X[12] = PLUSONE(ctx->X[12]);
|
||||
if (bytes <= 64) {
|
||||
for (i = 0; i < bytes; ++i) {
|
||||
c[i] = m[i] ^ output[i];
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 64; ++i) {
|
||||
c[i] = m[i] ^ output[i];
|
||||
}
|
||||
bytes -= 64;
|
||||
c += 64;
|
||||
m += 64;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* API to encrypt/decrypt a message of any size.
|
||||
*/
|
||||
int Chacha_Process(ChaCha* ctx, byte* output, const byte* input, word32 msglen)
|
||||
{
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
Chacha_encrypt_bytes(ctx, input, output, msglen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CHACHA*/
|
||||
|
@@ -1,178 +0,0 @@
|
||||
/* dh.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifndef NO_DH
|
||||
|
||||
#include <cyassl/ctaocrypt/dh.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
#ifndef USER_MATH_LIB
|
||||
#include <math.h>
|
||||
#define XPOW(x,y) pow((x),(y))
|
||||
#define XLOG(x) log((x))
|
||||
#else
|
||||
/* user's own math lib */
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
void InitDhKey(DhKey* key)
|
||||
{
|
||||
(void)key;
|
||||
/* TomsFastMath doesn't use memory allocation */
|
||||
#ifndef USE_FAST_MATH
|
||||
key->p.dp = 0;
|
||||
key->g.dp = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FreeDhKey(DhKey* key)
|
||||
{
|
||||
(void)key;
|
||||
/* TomsFastMath doesn't use memory allocation */
|
||||
#ifndef USE_FAST_MATH
|
||||
mp_clear(&key->p);
|
||||
mp_clear(&key->g);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static word32 DiscreteLogWorkFactor(word32 n)
|
||||
{
|
||||
/* assuming discrete log takes about the same time as factoring */
|
||||
if (n<5)
|
||||
return 0;
|
||||
else
|
||||
return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
|
||||
XPOW(XLOG((double)n), 2.0/3.0) - 5);
|
||||
}
|
||||
|
||||
|
||||
static int GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz)
|
||||
{
|
||||
int ret;
|
||||
word32 sz = mp_unsigned_bin_size(&key->p);
|
||||
sz = min(sz, 2 * DiscreteLogWorkFactor(sz * CYASSL_BIT_SIZE) /
|
||||
CYASSL_BIT_SIZE + 1);
|
||||
|
||||
ret = RNG_GenerateBlock(rng, priv, sz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
priv[0] |= 0x0C;
|
||||
|
||||
*privSz = sz;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz,
|
||||
byte* pub, word32* pubSz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mp_int x;
|
||||
mp_int y;
|
||||
|
||||
if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
|
||||
ret = MP_EXPTMOD_E;
|
||||
|
||||
if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
|
||||
ret = MP_TO_E;
|
||||
|
||||
if (ret == 0)
|
||||
*pubSz = mp_unsigned_bin_size(&y);
|
||||
|
||||
mp_clear(&y);
|
||||
mp_clear(&x);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz,
|
||||
byte* pub, word32* pubSz)
|
||||
{
|
||||
int ret = GeneratePrivate(key, rng, priv, privSz);
|
||||
|
||||
return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz);
|
||||
}
|
||||
|
||||
int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
|
||||
word32 privSz, const byte* otherPub, word32 pubSz)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mp_int x;
|
||||
mp_int y;
|
||||
mp_int z;
|
||||
|
||||
if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
|
||||
ret = MP_EXPTMOD_E;
|
||||
|
||||
if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
|
||||
ret = MP_TO_E;
|
||||
|
||||
if (ret == 0)
|
||||
*agreeSz = mp_unsigned_bin_size(&z);
|
||||
|
||||
mp_clear(&z);
|
||||
mp_clear(&y);
|
||||
mp_clear(&x);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* NO_DH */
|
||||
|
@@ -1,226 +0,0 @@
|
||||
/* dsa.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifndef NO_DSA
|
||||
|
||||
#include <cyassl/ctaocrypt/dsa.h>
|
||||
#include <cyassl/ctaocrypt/sha.h>
|
||||
#include <cyassl/ctaocrypt/random.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
|
||||
|
||||
enum {
|
||||
DSA_HALF_SIZE = 20, /* r and s size */
|
||||
DSA_SIG_SIZE = 40 /* signature size */
|
||||
};
|
||||
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
void InitDsaKey(DsaKey* key)
|
||||
{
|
||||
key->type = -1; /* haven't decided yet */
|
||||
|
||||
/* TomsFastMath doesn't use memory allocation */
|
||||
#ifndef USE_FAST_MATH
|
||||
key->p.dp = 0; /* public alloc parts */
|
||||
key->q.dp = 0;
|
||||
key->g.dp = 0;
|
||||
key->y.dp = 0;
|
||||
|
||||
key->x.dp = 0; /* private alloc parts */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void FreeDsaKey(DsaKey* key)
|
||||
{
|
||||
(void)key;
|
||||
/* TomsFastMath doesn't use memory allocation */
|
||||
#ifndef USE_FAST_MATH
|
||||
if (key->type == DSA_PRIVATE)
|
||||
mp_clear(&key->x);
|
||||
mp_clear(&key->y);
|
||||
mp_clear(&key->g);
|
||||
mp_clear(&key->q);
|
||||
mp_clear(&key->p);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng)
|
||||
{
|
||||
mp_int k, kInv, r, s, H;
|
||||
int ret, sz;
|
||||
byte buffer[DSA_HALF_SIZE];
|
||||
|
||||
sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q));
|
||||
|
||||
/* generate k */
|
||||
ret = RNG_GenerateBlock(rng, buffer, sz);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
buffer[0] |= 0x0C;
|
||||
|
||||
if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT)
|
||||
ret = MP_CMP_E;
|
||||
|
||||
/* inverse k mod q */
|
||||
if (ret == 0 && mp_invmod(&k, &key->q, &kInv) != MP_OKAY)
|
||||
ret = MP_INVMOD_E;
|
||||
|
||||
/* generate r, r = (g exp k mod p) mod q */
|
||||
if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY)
|
||||
ret = MP_EXPTMOD_E;
|
||||
|
||||
if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY)
|
||||
ret = MP_MOD_E;
|
||||
|
||||
/* generate H from sha digest */
|
||||
if (ret == 0 && mp_read_unsigned_bin(&H, digest,SHA_DIGEST_SIZE) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
/* generate s, s = (kInv * (H + x*r)) % q */
|
||||
if (ret == 0 && mp_mul(&key->x, &r, &s) != MP_OKAY)
|
||||
ret = MP_MUL_E;
|
||||
|
||||
if (ret == 0 && mp_add(&s, &H, &s) != MP_OKAY)
|
||||
ret = MP_ADD_E;
|
||||
|
||||
if (ret == 0 && mp_mulmod(&s, &kInv, &key->q, &s) != MP_OKAY)
|
||||
ret = MP_MULMOD_E;
|
||||
|
||||
/* write out */
|
||||
if (ret == 0) {
|
||||
int rSz = mp_unsigned_bin_size(&r);
|
||||
int sSz = mp_unsigned_bin_size(&s);
|
||||
|
||||
if (rSz == DSA_HALF_SIZE - 1) {
|
||||
out[0] = 0;
|
||||
out++;
|
||||
}
|
||||
|
||||
if (mp_to_unsigned_bin(&r, out) != MP_OKAY)
|
||||
ret = MP_TO_E;
|
||||
else {
|
||||
if (sSz == DSA_HALF_SIZE - 1) {
|
||||
out[rSz] = 0;
|
||||
out++;
|
||||
}
|
||||
ret = mp_to_unsigned_bin(&s, out + rSz);
|
||||
}
|
||||
}
|
||||
|
||||
mp_clear(&H);
|
||||
mp_clear(&s);
|
||||
mp_clear(&r);
|
||||
mp_clear(&kInv);
|
||||
mp_clear(&k);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int DsaVerify(const byte* digest, const byte* sig, DsaKey* key, int* answer)
|
||||
{
|
||||
mp_int w, u1, u2, v, r, s;
|
||||
int ret = 0;
|
||||
|
||||
if (mp_init_multi(&w, &u1, &u2, &v, &r, &s) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
/* set r and s from signature */
|
||||
if (mp_read_unsigned_bin(&r, sig, DSA_HALF_SIZE) != MP_OKAY ||
|
||||
mp_read_unsigned_bin(&s, sig + DSA_HALF_SIZE, DSA_HALF_SIZE) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
/* sanity checks */
|
||||
|
||||
|
||||
/* put H into u1 from sha digest */
|
||||
if (ret == 0 && mp_read_unsigned_bin(&u1,digest,SHA_DIGEST_SIZE) != MP_OKAY)
|
||||
ret = MP_READ_E;
|
||||
|
||||
/* w = s invmod q */
|
||||
if (ret == 0 && mp_invmod(&s, &key->q, &w) != MP_OKAY)
|
||||
ret = MP_INVMOD_E;
|
||||
|
||||
/* u1 = (H * w) % q */
|
||||
if (ret == 0 && mp_mulmod(&u1, &w, &key->q, &u1) != MP_OKAY)
|
||||
ret = MP_MULMOD_E;
|
||||
|
||||
/* u2 = (r * w) % q */
|
||||
if (ret == 0 && mp_mulmod(&r, &w, &key->q, &u2) != MP_OKAY)
|
||||
ret = MP_MULMOD_E;
|
||||
|
||||
/* verify v = ((g^u1 * y^u2) mod p) mod q */
|
||||
if (ret == 0 && mp_exptmod(&key->g, &u1, &key->p, &u1) != MP_OKAY)
|
||||
ret = MP_EXPTMOD_E;
|
||||
|
||||
if (ret == 0 && mp_exptmod(&key->y, &u2, &key->p, &u2) != MP_OKAY)
|
||||
ret = MP_EXPTMOD_E;
|
||||
|
||||
if (ret == 0 && mp_mulmod(&u1, &u2, &key->p, &v) != MP_OKAY)
|
||||
ret = MP_MULMOD_E;
|
||||
|
||||
if (ret == 0 && mp_mod(&v, &key->q, &v) != MP_OKAY)
|
||||
ret = MP_MULMOD_E;
|
||||
|
||||
/* do they match */
|
||||
if (ret == 0 && mp_cmp(&r, &v) == MP_EQ)
|
||||
*answer = 1;
|
||||
else
|
||||
*answer = 0;
|
||||
|
||||
mp_clear(&s);
|
||||
mp_clear(&r);
|
||||
mp_clear(&u1);
|
||||
mp_clear(&u2);
|
||||
mp_clear(&w);
|
||||
mp_clear(&v);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif /* NO_DSA */
|
||||
|
4837
ctaocrypt/src/ecc.c
4837
ctaocrypt/src/ecc.c
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
/* dummy ecc_fp.c for dist */
|
@@ -1,554 +0,0 @@
|
||||
/* poly1305.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
* Based off the public domain implementations by Andrew Moon
|
||||
* and Daniel J. Bernstein
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef HAVE_POLY1305
|
||||
#include <cyassl/ctaocrypt/poly1305.h>
|
||||
#include <cyassl/ctaocrypt/error-crypt.h>
|
||||
#include <cyassl/ctaocrypt/logging.h>
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* 4127 warning constant while(1) */
|
||||
#pragma warning(disable: 4127)
|
||||
#endif
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define POLY1305_NOINLINE __declspec(noinline)
|
||||
#elif defined(__GNUC__)
|
||||
#define POLY1305_NOINLINE __attribute__((noinline))
|
||||
#else
|
||||
#define POLY1305_NOINLINE
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
|
||||
typedef struct word128 {
|
||||
word64 lo;
|
||||
word64 hi;
|
||||
} word128;
|
||||
|
||||
#define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi)
|
||||
#define ADD(out, in) { word64 t = out.lo; out.lo += in.lo;
|
||||
out.hi += (out.lo < t) + in.hi; }
|
||||
#define ADDLO(out, in) { word64 t = out.lo; out.lo += in;
|
||||
out.hi += (out.lo < t); }
|
||||
#define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))
|
||||
#define LO(in) (in.lo)
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
typedef unsigned __int128 word128;
|
||||
#else
|
||||
typedef unsigned word128 __attribute__((mode(TI)));
|
||||
#endif
|
||||
|
||||
#define MUL(out, x, y) out = ((word128)x * y)
|
||||
#define ADD(out, in) out += in
|
||||
#define ADDLO(out, in) out += in
|
||||
#define SHR(in, shift) (word64)(in >> (shift))
|
||||
#define LO(in) (word64)(in)
|
||||
#endif
|
||||
|
||||
static word64 U8TO64(const byte* p) {
|
||||
return
|
||||
(((word64)(p[0] & 0xff) ) |
|
||||
((word64)(p[1] & 0xff) << 8) |
|
||||
((word64)(p[2] & 0xff) << 16) |
|
||||
((word64)(p[3] & 0xff) << 24) |
|
||||
((word64)(p[4] & 0xff) << 32) |
|
||||
((word64)(p[5] & 0xff) << 40) |
|
||||
((word64)(p[6] & 0xff) << 48) |
|
||||
((word64)(p[7] & 0xff) << 56));
|
||||
}
|
||||
|
||||
static void U64TO8(byte* p, word64 v) {
|
||||
p[0] = (v ) & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
p[4] = (v >> 32) & 0xff;
|
||||
p[5] = (v >> 40) & 0xff;
|
||||
p[6] = (v >> 48) & 0xff;
|
||||
p[7] = (v >> 56) & 0xff;
|
||||
}
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
static word32 U8TO32(const byte *p) {
|
||||
return
|
||||
(((word32)(p[0] & 0xff) ) |
|
||||
((word32)(p[1] & 0xff) << 8) |
|
||||
((word32)(p[2] & 0xff) << 16) |
|
||||
((word32)(p[3] & 0xff) << 24));
|
||||
}
|
||||
|
||||
static void U32TO8(byte *p, word32 v) {
|
||||
p[0] = (v ) & 0xff;
|
||||
p[1] = (v >> 8) & 0xff;
|
||||
p[2] = (v >> 16) & 0xff;
|
||||
p[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void poly1305_blocks(Poly1305* ctx, const unsigned char *m,
|
||||
size_t bytes) {
|
||||
|
||||
#ifdef POLY130564
|
||||
|
||||
const word64 hibit = (ctx->final) ? 0 : ((word64)1 << 40); /* 1 << 128 */
|
||||
word64 r0,r1,r2;
|
||||
word64 s1,s2;
|
||||
word64 h0,h1,h2;
|
||||
word64 c;
|
||||
word128 d0,d1,d2,d;
|
||||
|
||||
#else
|
||||
|
||||
const word32 hibit = (ctx->final) ? 0 : (1 << 24); /* 1 << 128 */
|
||||
word32 r0,r1,r2,r3,r4;
|
||||
word32 s1,s2,s3,s4;
|
||||
word32 h0,h1,h2,h3,h4;
|
||||
word64 d0,d1,d2,d3,d4;
|
||||
word32 c;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef POLY130564
|
||||
|
||||
r0 = ctx->r[0];
|
||||
r1 = ctx->r[1];
|
||||
r2 = ctx->r[2];
|
||||
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
|
||||
s1 = r1 * (5 << 2);
|
||||
s2 = r2 * (5 << 2);
|
||||
|
||||
while (bytes >= POLY1305_BLOCK_SIZE) {
|
||||
word64 t0,t1;
|
||||
|
||||
/* h += m[i] */
|
||||
t0 = U8TO64(&m[0]);
|
||||
t1 = U8TO64(&m[8]);
|
||||
|
||||
h0 += (( t0 ) & 0xfffffffffff);
|
||||
h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff);
|
||||
h2 += (((t1 >> 24) ) & 0x3ffffffffff) | hibit;
|
||||
|
||||
/* h *= r */
|
||||
MUL(d0, h0, r0); MUL(d, h1, s2); ADD(d0, d); MUL(d, h2, s1); ADD(d0, d);
|
||||
MUL(d1, h0, r1); MUL(d, h1, r0); ADD(d1, d); MUL(d, h2, s2); ADD(d1, d);
|
||||
MUL(d2, h0, r2); MUL(d, h1, r1); ADD(d2, d); MUL(d, h2, r0); ADD(d2, d);
|
||||
|
||||
/* (partial) h %= p */
|
||||
c = SHR(d0, 44); h0 = LO(d0) & 0xfffffffffff;
|
||||
ADDLO(d1, c); c = SHR(d1, 44); h1 = LO(d1) & 0xfffffffffff;
|
||||
ADDLO(d2, c); c = SHR(d2, 42); h2 = LO(d2) & 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 = h0 & 0xfffffffffff;
|
||||
h1 += c;
|
||||
|
||||
m += POLY1305_BLOCK_SIZE;
|
||||
bytes -= POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
ctx->h[0] = h0;
|
||||
ctx->h[1] = h1;
|
||||
ctx->h[2] = h2;
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
r0 = ctx->r[0];
|
||||
r1 = ctx->r[1];
|
||||
r2 = ctx->r[2];
|
||||
r3 = ctx->r[3];
|
||||
r4 = ctx->r[4];
|
||||
|
||||
s1 = r1 * 5;
|
||||
s2 = r2 * 5;
|
||||
s3 = r3 * 5;
|
||||
s4 = r4 * 5;
|
||||
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
h3 = ctx->h[3];
|
||||
h4 = ctx->h[4];
|
||||
|
||||
while (bytes >= POLY1305_BLOCK_SIZE) {
|
||||
/* h += m[i] */
|
||||
h0 += (U8TO32(m+ 0) ) & 0x3ffffff;
|
||||
h1 += (U8TO32(m+ 3) >> 2) & 0x3ffffff;
|
||||
h2 += (U8TO32(m+ 6) >> 4) & 0x3ffffff;
|
||||
h3 += (U8TO32(m+ 9) >> 6) & 0x3ffffff;
|
||||
h4 += (U8TO32(m+12) >> 8) | hibit;
|
||||
|
||||
/* h *= r */
|
||||
d0 = ((word64)h0 * r0) + ((word64)h1 * s4) + ((word64)h2 * s3) +
|
||||
((word64)h3 * s2) + ((word64)h4 * s1);
|
||||
d1 = ((word64)h0 * r1) + ((word64)h1 * r0) + ((word64)h2 * s4) +
|
||||
((word64)h3 * s3) + ((word64)h4 * s2);
|
||||
d2 = ((word64)h0 * r2) + ((word64)h1 * r1) + ((word64)h2 * r0) +
|
||||
((word64)h3 * s4) + ((word64)h4 * s3);
|
||||
d3 = ((word64)h0 * r3) + ((word64)h1 * r2) + ((word64)h2 * r1) +
|
||||
((word64)h3 * r0) + ((word64)h4 * s4);
|
||||
d4 = ((word64)h0 * r4) + ((word64)h1 * r3) + ((word64)h2 * r2) +
|
||||
((word64)h3 * r1) + ((word64)h4 * r0);
|
||||
|
||||
/* (partial) h %= p */
|
||||
c = (word32)(d0 >> 26); h0 = (word32)d0 & 0x3ffffff;
|
||||
d1 += c; c = (word32)(d1 >> 26); h1 = (word32)d1 & 0x3ffffff;
|
||||
d2 += c; c = (word32)(d2 >> 26); h2 = (word32)d2 & 0x3ffffff;
|
||||
d3 += c; c = (word32)(d3 >> 26); h3 = (word32)d3 & 0x3ffffff;
|
||||
d4 += c; c = (word32)(d4 >> 26); h4 = (word32)d4 & 0x3ffffff;
|
||||
h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff;
|
||||
h1 += c;
|
||||
|
||||
m += POLY1305_BLOCK_SIZE;
|
||||
bytes -= POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
ctx->h[0] = h0;
|
||||
ctx->h[1] = h1;
|
||||
ctx->h[2] = h2;
|
||||
ctx->h[3] = h3;
|
||||
ctx->h[4] = h4;
|
||||
|
||||
#endif /* end of 64 bit cpu blocks or 32 bit cpu */
|
||||
}
|
||||
|
||||
|
||||
int Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) {
|
||||
|
||||
#if defined(POLY130564)
|
||||
word64 t0,t1;
|
||||
#endif
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 k;
|
||||
printf("Poly key used:\n");
|
||||
for (k = 0; k < keySz; k++) {
|
||||
printf("%02x", key[k]);
|
||||
if ((k+1) % 8 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if (keySz != 32 || ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
t0 = U8TO64(key + 0);
|
||||
t1 = U8TO64(key + 8);
|
||||
|
||||
ctx->r[0] = ( t0 ) & 0xffc0fffffff;
|
||||
ctx->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff;
|
||||
ctx->r[2] = ((t1 >> 24) ) & 0x00ffffffc0f;
|
||||
|
||||
/* h (accumulator) = 0 */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
|
||||
/* save pad for later */
|
||||
ctx->pad[0] = U8TO64(key + 16);
|
||||
ctx->pad[1] = U8TO64(key + 24);
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
ctx->r[0] = (U8TO32(key + 0) ) & 0x3ffffff;
|
||||
ctx->r[1] = (U8TO32(key + 3) >> 2) & 0x3ffff03;
|
||||
ctx->r[2] = (U8TO32(key + 6) >> 4) & 0x3ffc0ff;
|
||||
ctx->r[3] = (U8TO32(key + 9) >> 6) & 0x3f03fff;
|
||||
ctx->r[4] = (U8TO32(key + 12) >> 8) & 0x00fffff;
|
||||
|
||||
/* h = 0 */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
ctx->h[3] = 0;
|
||||
ctx->h[4] = 0;
|
||||
|
||||
/* save pad for later */
|
||||
ctx->pad[0] = U8TO32(key + 16);
|
||||
ctx->pad[1] = U8TO32(key + 20);
|
||||
ctx->pad[2] = U8TO32(key + 24);
|
||||
ctx->pad[3] = U8TO32(key + 28);
|
||||
|
||||
#endif
|
||||
|
||||
ctx->leftover = 0;
|
||||
ctx->final = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Poly1305Final(Poly1305* ctx, byte* mac) {
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
word64 h0,h1,h2,c;
|
||||
word64 g0,g1,g2;
|
||||
word64 t0,t1;
|
||||
|
||||
#else
|
||||
|
||||
word32 h0,h1,h2,h3,h4,c;
|
||||
word32 g0,g1,g2,g3,g4;
|
||||
word64 f;
|
||||
word32 mask;
|
||||
|
||||
#endif
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(POLY130564)
|
||||
|
||||
/* process the remaining block */
|
||||
if (ctx->leftover) {
|
||||
size_t i = ctx->leftover;
|
||||
ctx->buffer[i] = 1;
|
||||
for (i = i + 1; i < POLY1305_BLOCK_SIZE; i++)
|
||||
ctx->buffer[i] = 0;
|
||||
ctx->final = 1;
|
||||
poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* fully carry h */
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
|
||||
c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c; c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += c; c = (h2 >> 42); h2 &= 0x3ffffffffff;
|
||||
h0 += c * 5; c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += c;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5; c = (g0 >> 44); g0 &= 0xfffffffffff;
|
||||
g1 = h1 + c; c = (g1 >> 44); g1 &= 0xfffffffffff;
|
||||
g2 = h2 + c - ((word64)1 << 42);
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
c = (g2 >> ((sizeof(word64) * 8) - 1)) - 1;
|
||||
g0 &= c;
|
||||
g1 &= c;
|
||||
g2 &= c;
|
||||
c = ~c;
|
||||
h0 = (h0 & c) | g0;
|
||||
h1 = (h1 & c) | g1;
|
||||
h2 = (h2 & c) | g2;
|
||||
|
||||
/* h = (h + pad) */
|
||||
t0 = ctx->pad[0];
|
||||
t1 = ctx->pad[1];
|
||||
|
||||
h0 += (( t0 ) & 0xfffffffffff) ;
|
||||
c = (h0 >> 44); h0 &= 0xfffffffffff;
|
||||
h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c;
|
||||
c = (h1 >> 44); h1 &= 0xfffffffffff;
|
||||
h2 += (((t1 >> 24) ) & 0x3ffffffffff) + c;
|
||||
h2 &= 0x3ffffffffff;
|
||||
|
||||
/* mac = h % (2^128) */
|
||||
h0 = ((h0 ) | (h1 << 44));
|
||||
h1 = ((h1 >> 20) | (h2 << 24));
|
||||
|
||||
U64TO8(mac + 0, h0);
|
||||
U64TO8(mac + 8, h1);
|
||||
|
||||
/* zero out the state */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
ctx->r[0] = 0;
|
||||
ctx->r[1] = 0;
|
||||
ctx->r[2] = 0;
|
||||
ctx->pad[0] = 0;
|
||||
ctx->pad[1] = 0;
|
||||
|
||||
#else /* if not 64 bit then use 32 bit */
|
||||
|
||||
/* process the remaining block */
|
||||
if (ctx->leftover) {
|
||||
size_t i = ctx->leftover;
|
||||
ctx->buffer[i++] = 1;
|
||||
for (; i < POLY1305_BLOCK_SIZE; i++)
|
||||
ctx->buffer[i] = 0;
|
||||
ctx->final = 1;
|
||||
poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/* fully carry h */
|
||||
h0 = ctx->h[0];
|
||||
h1 = ctx->h[1];
|
||||
h2 = ctx->h[2];
|
||||
h3 = ctx->h[3];
|
||||
h4 = ctx->h[4];
|
||||
|
||||
c = h1 >> 26; h1 = h1 & 0x3ffffff;
|
||||
h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff;
|
||||
h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff;
|
||||
h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff;
|
||||
h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff;
|
||||
h1 += c;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff;
|
||||
g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff;
|
||||
g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff;
|
||||
g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff;
|
||||
g4 = h4 + c - (1 << 26);
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
mask = (g4 >> ((sizeof(word32) * 8) - 1)) - 1;
|
||||
g0 &= mask;
|
||||
g1 &= mask;
|
||||
g2 &= mask;
|
||||
g3 &= mask;
|
||||
g4 &= mask;
|
||||
mask = ~mask;
|
||||
h0 = (h0 & mask) | g0;
|
||||
h1 = (h1 & mask) | g1;
|
||||
h2 = (h2 & mask) | g2;
|
||||
h3 = (h3 & mask) | g3;
|
||||
h4 = (h4 & mask) | g4;
|
||||
|
||||
/* h = h % (2^128) */
|
||||
h0 = ((h0 ) | (h1 << 26)) & 0xffffffff;
|
||||
h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff;
|
||||
h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff;
|
||||
h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff;
|
||||
|
||||
/* mac = (h + pad) % (2^128) */
|
||||
f = (word64)h0 + ctx->pad[0] ; h0 = (word32)f;
|
||||
f = (word64)h1 + ctx->pad[1] + (f >> 32); h1 = (word32)f;
|
||||
f = (word64)h2 + ctx->pad[2] + (f >> 32); h2 = (word32)f;
|
||||
f = (word64)h3 + ctx->pad[3] + (f >> 32); h3 = (word32)f;
|
||||
|
||||
U32TO8(mac + 0, h0);
|
||||
U32TO8(mac + 4, h1);
|
||||
U32TO8(mac + 8, h2);
|
||||
U32TO8(mac + 12, h3);
|
||||
|
||||
/* zero out the state */
|
||||
ctx->h[0] = 0;
|
||||
ctx->h[1] = 0;
|
||||
ctx->h[2] = 0;
|
||||
ctx->h[3] = 0;
|
||||
ctx->h[4] = 0;
|
||||
ctx->r[0] = 0;
|
||||
ctx->r[1] = 0;
|
||||
ctx->r[2] = 0;
|
||||
ctx->r[3] = 0;
|
||||
ctx->r[4] = 0;
|
||||
ctx->pad[0] = 0;
|
||||
ctx->pad[1] = 0;
|
||||
ctx->pad[2] = 0;
|
||||
ctx->pad[3] = 0;
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) {
|
||||
|
||||
size_t i;
|
||||
|
||||
#ifdef CHACHA_AEAD_TEST
|
||||
word32 k;
|
||||
printf("Raw input to poly:\n");
|
||||
for (k = 0; k < bytes; k++) {
|
||||
printf("%02x", m[k]);
|
||||
if ((k+1) % 16 == 0)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* handle leftover */
|
||||
if (ctx->leftover) {
|
||||
size_t want = (POLY1305_BLOCK_SIZE - ctx->leftover);
|
||||
if (want > bytes)
|
||||
want = bytes;
|
||||
for (i = 0; i < want; i++)
|
||||
ctx->buffer[ctx->leftover + i] = m[i];
|
||||
bytes -= want;
|
||||
m += want;
|
||||
ctx->leftover += want;
|
||||
if (ctx->leftover < POLY1305_BLOCK_SIZE)
|
||||
return 0;
|
||||
poly1305_blocks(ctx, ctx->buffer, POLY1305_BLOCK_SIZE);
|
||||
ctx->leftover = 0;
|
||||
}
|
||||
|
||||
/* process full blocks */
|
||||
if (bytes >= POLY1305_BLOCK_SIZE) {
|
||||
size_t want = (bytes & ~(POLY1305_BLOCK_SIZE - 1));
|
||||
poly1305_blocks(ctx, m, want);
|
||||
m += want;
|
||||
bytes -= want;
|
||||
}
|
||||
|
||||
/* store leftover */
|
||||
if (bytes) {
|
||||
for (i = 0; i < bytes; i++)
|
||||
ctx->buffer[ctx->leftover + i] = m[i];
|
||||
ctx->leftover += bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_POLY1305 */
|
||||
|
@@ -1,354 +0,0 @@
|
||||
/* ripemd.c
|
||||
*
|
||||
* Copyright (C) 2006-2014 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL. (formerly known as CyaSSL)
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <cyassl/ctaocrypt/settings.h>
|
||||
|
||||
#ifdef CYASSL_RIPEMD
|
||||
|
||||
#include <cyassl/ctaocrypt/ripemd.h>
|
||||
#ifdef NO_INLINE
|
||||
#include <cyassl/ctaocrypt/misc.h>
|
||||
#else
|
||||
#include <ctaocrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef min
|
||||
|
||||
static INLINE word32 min(word32 a, word32 b)
|
||||
{
|
||||
return a > b ? b : a;
|
||||
}
|
||||
|
||||
#endif /* min */
|
||||
|
||||
|
||||
void InitRipeMd(RipeMd* ripemd)
|
||||
{
|
||||
ripemd->digest[0] = 0x67452301L;
|
||||
ripemd->digest[1] = 0xEFCDAB89L;
|
||||
ripemd->digest[2] = 0x98BADCFEL;
|
||||
ripemd->digest[3] = 0x10325476L;
|
||||
ripemd->digest[4] = 0xC3D2E1F0L;
|
||||
|
||||
ripemd->buffLen = 0;
|
||||
ripemd->loLen = 0;
|
||||
ripemd->hiLen = 0;
|
||||
}
|
||||
|
||||
|
||||
/* for all */
|
||||
#define F(x, y, z) (x ^ y ^ z)
|
||||
#define G(x, y, z) (z ^ (x & (y^z)))
|
||||
#define H(x, y, z) (z ^ (x | ~y))
|
||||
#define I(x, y, z) (y ^ (z & (x^y)))
|
||||
#define J(x, y, z) (x ^ (y | ~z))
|
||||
|
||||
#define k0 0
|
||||
#define k1 0x5a827999
|
||||
#define k2 0x6ed9eba1
|
||||
#define k3 0x8f1bbcdc
|
||||
#define k4 0xa953fd4e
|
||||
#define k5 0x50a28be6
|
||||
#define k6 0x5c4dd124
|
||||
#define k7 0x6d703ef3
|
||||
#define k8 0x7a6d76e9
|
||||
#define k9 0
|
||||
|
||||
/* for 160 and 320 */
|
||||
#define Subround(f, a, b, c, d, e, x, s, k) \
|
||||
a += f(b, c, d) + x + k;\
|
||||
a = rotlFixed((word32)a, s) + e;\
|
||||
c = rotlFixed((word32)c, 10U)
|
||||
|
||||
static void Transform(RipeMd* ripemd)
|
||||
{
|
||||
word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2;
|
||||
a1 = a2 = ripemd->digest[0];
|
||||
b1 = b2 = ripemd->digest[1];
|
||||
c1 = c2 = ripemd->digest[2];
|
||||
d1 = d2 = ripemd->digest[3];
|
||||
e1 = e2 = ripemd->digest[4];
|
||||
|
||||
Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 11, k0);
|
||||
Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 1], 14, k0);
|
||||
Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 2], 15, k0);
|
||||
Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 12, k0);
|
||||
Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 4], 5, k0);
|
||||
Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[ 5], 8, k0);
|
||||
Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[ 6], 7, k0);
|
||||
Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[ 7], 9, k0);
|
||||
Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 11, k0);
|
||||
Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 13, k0);
|
||||
Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[10], 14, k0);
|
||||
Subround(F, e1, a1, b1, c1, d1, ripemd->buffer[11], 15, k0);
|
||||
Subround(F, d1, e1, a1, b1, c1, ripemd->buffer[12], 6, k0);
|
||||
Subround(F, c1, d1, e1, a1, b1, ripemd->buffer[13], 7, k0);
|
||||
Subround(F, b1, c1, d1, e1, a1, ripemd->buffer[14], 9, k0);
|
||||
Subround(F, a1, b1, c1, d1, e1, ripemd->buffer[15], 8, k0);
|
||||
|
||||
Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 7], 7, k1);
|
||||
Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 4], 6, k1);
|
||||
Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[13], 8, k1);
|
||||
Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 13, k1);
|
||||
Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[10], 11, k1);
|
||||
Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 6], 9, k1);
|
||||
Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[15], 7, k1);
|
||||
Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 3], 15, k1);
|
||||
Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[12], 7, k1);
|
||||
Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 12, k1);
|
||||
Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 15, k1);
|
||||
Subround(G, d1, e1, a1, b1, c1, ripemd->buffer[ 5], 9, k1);
|
||||
Subround(G, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 11, k1);
|
||||
Subround(G, b1, c1, d1, e1, a1, ripemd->buffer[14], 7, k1);
|
||||
Subround(G, a1, b1, c1, d1, e1, ripemd->buffer[11], 13, k1);
|
||||
Subround(G, e1, a1, b1, c1, d1, ripemd->buffer[ 8], 12, k1);
|
||||
|
||||
Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 11, k2);
|
||||
Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[10], 13, k2);
|
||||
Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[14], 6, k2);
|
||||
Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 4], 7, k2);
|
||||
Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 9], 14, k2);
|
||||
Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[15], 9, k2);
|
||||
Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 13, k2);
|
||||
Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[ 1], 15, k2);
|
||||
Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 14, k2);
|
||||
Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 7], 8, k2);
|
||||
Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 13, k2);
|
||||
Subround(H, c1, d1, e1, a1, b1, ripemd->buffer[ 6], 6, k2);
|
||||
Subround(H, b1, c1, d1, e1, a1, ripemd->buffer[13], 5, k2);
|
||||
Subround(H, a1, b1, c1, d1, e1, ripemd->buffer[11], 12, k2);
|
||||
Subround(H, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 7, k2);
|
||||
Subround(H, d1, e1, a1, b1, c1, ripemd->buffer[12], 5, k2);
|
||||
|
||||
Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 11, k3);
|
||||
Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[ 9], 12, k3);
|
||||
Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[11], 14, k3);
|
||||
Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[10], 15, k3);
|
||||
Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 0], 14, k3);
|
||||
Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 8], 15, k3);
|
||||
Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[12], 9, k3);
|
||||
Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[ 4], 8, k3);
|
||||
Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[13], 9, k3);
|
||||
Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 3], 14, k3);
|
||||
Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 7], 5, k3);
|
||||
Subround(I, b1, c1, d1, e1, a1, ripemd->buffer[15], 6, k3);
|
||||
Subround(I, a1, b1, c1, d1, e1, ripemd->buffer[14], 8, k3);
|
||||
Subround(I, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 6, k3);
|
||||
Subround(I, d1, e1, a1, b1, c1, ripemd->buffer[ 6], 5, k3);
|
||||
Subround(I, c1, d1, e1, a1, b1, ripemd->buffer[ 2], 12, k3);
|
||||
|
||||
Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 4], 9, k4);
|
||||
Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 0], 15, k4);
|
||||
Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[ 5], 5, k4);
|
||||
Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 9], 11, k4);
|
||||
Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 7], 6, k4);
|
||||
Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[12], 8, k4);
|
||||
Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 2], 13, k4);
|
||||
Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[10], 12, k4);
|
||||
Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[14], 5, k4);
|
||||
Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[ 1], 12, k4);
|
||||
Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[ 3], 13, k4);
|
||||
Subround(J, a1, b1, c1, d1, e1, ripemd->buffer[ 8], 14, k4);
|
||||
Subround(J, e1, a1, b1, c1, d1, ripemd->buffer[11], 11, k4);
|
||||
Subround(J, d1, e1, a1, b1, c1, ripemd->buffer[ 6], 8, k4);
|
||||
Subround(J, c1, d1, e1, a1, b1, ripemd->buffer[15], 5, k4);
|
||||
Subround(J, b1, c1, d1, e1, a1, ripemd->buffer[13], 6, k4);
|
||||
|
||||
Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 5], 8, k5);
|
||||
Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[14], 9, k5);
|
||||
Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 7], 9, k5);
|
||||
Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[ 0], 11, k5);
|
||||
Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 13, k5);
|
||||
Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[ 2], 15, k5);
|
||||
Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[11], 15, k5);
|
||||
Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 4], 5, k5);
|
||||
Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[13], 7, k5);
|
||||
Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 6], 7, k5);
|
||||
Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[15], 8, k5);
|
||||
Subround(J, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 11, k5);
|
||||
Subround(J, d2, e2, a2, b2, c2, ripemd->buffer[ 1], 14, k5);
|
||||
Subround(J, c2, d2, e2, a2, b2, ripemd->buffer[10], 14, k5);
|
||||
Subround(J, b2, c2, d2, e2, a2, ripemd->buffer[ 3], 12, k5);
|
||||
Subround(J, a2, b2, c2, d2, e2, ripemd->buffer[12], 6, k5);
|
||||
|
||||
Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 6], 9, k6);
|
||||
Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[11], 13, k6);
|
||||
Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 3], 15, k6);
|
||||
Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 7], 7, k6);
|
||||
Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 12, k6);
|
||||
Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[13], 8, k6);
|
||||
Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[ 5], 9, k6);
|
||||
Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[10], 11, k6);
|
||||
Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[14], 7, k6);
|
||||
Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[15], 7, k6);
|
||||
Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 12, k6);
|
||||
Subround(I, d2, e2, a2, b2, c2, ripemd->buffer[12], 7, k6);
|
||||
Subround(I, c2, d2, e2, a2, b2, ripemd->buffer[ 4], 6, k6);
|
||||
Subround(I, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 15, k6);
|
||||
Subround(I, a2, b2, c2, d2, e2, ripemd->buffer[ 1], 13, k6);
|
||||
Subround(I, e2, a2, b2, c2, d2, ripemd->buffer[ 2], 11, k6);
|
||||
|
||||
Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[15], 9, k7);
|
||||
Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 5], 7, k7);
|
||||
Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 1], 15, k7);
|
||||
Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 3], 11, k7);
|
||||
Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 8, k7);
|
||||
Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[14], 6, k7);
|
||||
Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 6], 6, k7);
|
||||
Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[ 9], 14, k7);
|
||||
Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[11], 12, k7);
|
||||
Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 8], 13, k7);
|
||||
Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[12], 5, k7);
|
||||
Subround(H, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 14, k7);
|
||||
Subround(H, b2, c2, d2, e2, a2, ripemd->buffer[10], 13, k7);
|
||||
Subround(H, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 13, k7);
|
||||
Subround(H, e2, a2, b2, c2, d2, ripemd->buffer[ 4], 7, k7);
|
||||
Subround(H, d2, e2, a2, b2, c2, ripemd->buffer[13], 5, k7);
|
||||
|
||||
Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 8], 15, k8);
|
||||
Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[ 6], 5, k8);
|
||||
Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 4], 8, k8);
|
||||
Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 1], 11, k8);
|
||||
Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 14, k8);
|
||||
Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[11], 14, k8);
|
||||
Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[15], 6, k8);
|
||||
Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 0], 14, k8);
|
||||
Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 5], 6, k8);
|
||||
Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[12], 9, k8);
|
||||
Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 12, k8);
|
||||
Subround(G, b2, c2, d2, e2, a2, ripemd->buffer[13], 9, k8);
|
||||
Subround(G, a2, b2, c2, d2, e2, ripemd->buffer[ 9], 12, k8);
|
||||
Subround(G, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 5, k8);
|
||||
Subround(G, d2, e2, a2, b2, c2, ripemd->buffer[10], 15, k8);
|
||||
Subround(G, c2, d2, e2, a2, b2, ripemd->buffer[14], 8, k8);
|
||||
|
||||
Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[12], 8, k9);
|
||||
Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[15], 5, k9);
|
||||
Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[10], 12, k9);
|
||||
Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 4], 9, k9);
|
||||
Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 1], 12, k9);
|
||||
Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[ 5], 5, k9);
|
||||
Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[ 8], 14, k9);
|
||||
Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 7], 6, k9);
|
||||
Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 6], 8, k9);
|
||||
Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 2], 13, k9);
|
||||
Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[13], 6, k9);
|
||||
Subround(F, a2, b2, c2, d2, e2, ripemd->buffer[14], 5, k9);
|
||||
Subround(F, e2, a2, b2, c2, d2, ripemd->buffer[ 0], 15, k9);
|
||||
Subround(F, d2, e2, a2, b2, c2, ripemd->buffer[ 3], 13, k9);
|
||||
Subround(F, c2, d2, e2, a2, b2, ripemd->buffer[ 9], 11, k9);
|
||||
Subround(F, b2, c2, d2, e2, a2, ripemd->buffer[11], 11, k9);
|
||||
|
||||
c1 = ripemd->digest[1] + c1 + d2;
|
||||
ripemd->digest[1] = ripemd->digest[2] + d1 + e2;
|
||||
ripemd->digest[2] = ripemd->digest[3] + e1 + a2;
|
||||
ripemd->digest[3] = ripemd->digest[4] + a1 + b2;
|
||||
ripemd->digest[4] = ripemd->digest[0] + b1 + c2;
|
||||
ripemd->digest[0] = c1;
|
||||
}
|
||||
|
||||
|
||||
static INLINE void AddLength(RipeMd* ripemd, word32 len)
|
||||
{
|
||||
word32 tmp = ripemd->loLen;
|
||||
if ( (ripemd->loLen += len) < tmp)
|
||||
ripemd->hiLen++; /* carry low to high */
|
||||
}
|
||||
|
||||
|
||||
void RipeMdUpdate(RipeMd* ripemd, const byte* data, word32 len)
|
||||
{
|
||||
/* do block size increments */
|
||||
byte* local = (byte*)ripemd->buffer;
|
||||
|
||||
while (len) {
|
||||
word32 add = min(len, RIPEMD_BLOCK_SIZE - ripemd->buffLen);
|
||||
XMEMCPY(&local[ripemd->buffLen], data, add);
|
||||
|
||||
ripemd->buffLen += add;
|
||||
data += add;
|
||||
len -= add;
|
||||
|
||||
if (ripemd->buffLen == RIPEMD_BLOCK_SIZE) {
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
ByteReverseWords(ripemd->buffer, ripemd->buffer,
|
||||
RIPEMD_BLOCK_SIZE);
|
||||
#endif
|
||||
Transform(ripemd);
|
||||
AddLength(ripemd, RIPEMD_BLOCK_SIZE);
|
||||
ripemd->buffLen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RipeMdFinal(RipeMd* ripemd, byte* hash)
|
||||
{
|
||||
byte* local = (byte*)ripemd->buffer;
|
||||
|
||||
AddLength(ripemd, ripemd->buffLen); /* before adding pads */
|
||||
|
||||
local[ripemd->buffLen++] = 0x80; /* add 1 */
|
||||
|
||||
/* pad with zeros */
|
||||
if (ripemd->buffLen > RIPEMD_PAD_SIZE) {
|
||||
XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_BLOCK_SIZE - ripemd->buffLen);
|
||||
ripemd->buffLen += RIPEMD_BLOCK_SIZE - ripemd->buffLen;
|
||||
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE);
|
||||
#endif
|
||||
Transform(ripemd);
|
||||
ripemd->buffLen = 0;
|
||||
}
|
||||
XMEMSET(&local[ripemd->buffLen], 0, RIPEMD_PAD_SIZE - ripemd->buffLen);
|
||||
|
||||
/* put lengths in bits */
|
||||
ripemd->loLen = ripemd->loLen << 3;
|
||||
ripemd->hiLen = (ripemd->loLen >> (8*sizeof(ripemd->loLen) - 3)) +
|
||||
(ripemd->hiLen << 3);
|
||||
|
||||
/* store lengths */
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
ByteReverseWords(ripemd->buffer, ripemd->buffer, RIPEMD_BLOCK_SIZE);
|
||||
#endif
|
||||
/* ! length ordering dependent on digest endian type ! */
|
||||
XMEMCPY(&local[RIPEMD_PAD_SIZE], &ripemd->loLen, sizeof(word32));
|
||||
XMEMCPY(&local[RIPEMD_PAD_SIZE + sizeof(word32)], &ripemd->hiLen,
|
||||
sizeof(word32));
|
||||
|
||||
Transform(ripemd);
|
||||
#ifdef BIG_ENDIAN_ORDER
|
||||
ByteReverseWords(ripemd->digest, ripemd->digest, RIPEMD_DIGEST_SIZE);
|
||||
#endif
|
||||
XMEMCPY(hash, ripemd->digest, RIPEMD_DIGEST_SIZE);
|
||||
|
||||
InitRipeMd(ripemd); /* reset state */
|
||||
}
|
||||
|
||||
|
||||
#endif /* CYASSL_RIPEMD */
|
Reference in New Issue
Block a user