c files for pkcs, poly, rabbit and ripemd

This commit is contained in:
Jacob Barthelmeh
2014-12-17 15:47:00 -07:00
parent 0da381e019
commit 664a40844c
6 changed files with 3588 additions and 2 deletions

View File

@@ -337,6 +337,9 @@
* needs investigation in regards to macros in fips */
#define WOLFSSL_MAX_16BIT CYASSL_MAX_16BIT
#define WOLFSSL_MSG(x) CYASSL_MSG(x)
#define NO_WOLFSSL_ALLOC_ALIGN NO_CYASSL_ALLOC_ALIGN /* @TODO*/
/* for arc4 reverse compatibility */
#ifndef NO_RC4
@@ -376,14 +379,13 @@
/* for hc128 reverse compatibility */
#ifdef HAVE_HC128
#define NO_WOLFSSL_ALLOC_ALIGN NO_CYASSL_ALLOC_ALIGN /* @TODO*/
#define Hc128_Process wc_Hc128_Process
#define Hc128_SetKey wc_Hc128_SetKey
#endif
/* for md2 reverse compatibility */
#define CYASSL_MD2 WOLFSSL_MD@ /* @TODO */
#define CYASSL_MD2 WOLFSSL_MD2 /* @TODO */
#ifdef WOLFSSL_MD2
#define InitMd2 wc_InitMd2
#define Md2Update wc_Md2Update
@@ -409,6 +411,49 @@
#endif
/* for poly1305 reverse compatibility */
#ifdef HAVE_POLY1305
#define Poly1305SetKey wc_Poly1305SetKey
#define Poly1305Update wc_Poly1305Update
#define Poly1305Final wc_Poly1305Final
#endif
/* for rabbit reverse compatibility */
#ifndef NO_RABBIT
#define RabbitProcess wc_RabbitProcess
#define RabbitSetKey wc_RabbitSetKey
#endif
/* for ripemd reverse compatibility */
#define CYASSL_RIPEMD WOLFSSL_RIPEMD /* @TODO */
#ifdef WOLFSSL_RIPEMD
#define InitRipeMd wc_InitRipeMd
#define RipeMdUpdate wc_RipeMdUpdate
#define RipeMdFinal wc_RipeMdFinal
#endif
/* for pkcs7 reverse compatibility */
#ifdef HAVE_PKCS7
#define SetContentType wc_SetContentType
#define GetContentType wc_GetContentType
#define CreateRecipientInfo wc_CreateRecipientInfo
#define PKCS7_InitWithCert wc_PKCS7_InitWithCert
#define PKCS7_Free wc_PKCS7_Free
#define PKCS7_EncodeData wc_PKCS7_EncodeData
#define PKCS7_EncodeSignedData wc_PKCS7_EncodeSignedData
#define PKCS7_VerifySignedData wc_PKCS7_VerifySignedData
#define PKCS7_EncodeEnvelopedData wc_PKCS7_EncodeEnvelopedData
#define PKCS7_DecodeEnvelopedData wc_PKCS7_DecodeEnvelopedData
#endif
/* for pwdbased reverse compatibility */
#ifdef __cplusplus
} /* extern "C" */

1849
wolfcrypt/src/pkcs7.c Normal file

File diff suppressed because it is too large Load Diff

554
wolfcrypt/src/poly1305.c Normal file
View File

@@ -0,0 +1,554 @@
/* 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 wc_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 wc_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 wc_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 */

474
wolfcrypt/src/pwdbased.c Normal file
View File

@@ -0,0 +1,474 @@
/* pwdbased.c
*
* Copyright (C) 2006-2014 wolfSSL Inc.
*
* This file is part of CyaSSL.
*
* CyaSSL 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.
*
* CyaSSL 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_PWDBASED
#ifdef CYASSL_PIC32MZ_HASH
#define InitMd5 InitMd5_sw
#define Md5Update Md5Update_sw
#define Md5Final Md5Final_sw
#define InitSha InitSha_sw
#define ShaUpdate ShaUpdate_sw
#define ShaFinal ShaFinal_sw
#define InitSha256 InitSha256_sw
#define Sha256Update Sha256Update_sw
#define Sha256Final Sha256Final_sw
#endif
#include <cyassl/ctaocrypt/pwdbased.h>
#include <cyassl/ctaocrypt/hmac.h>
#include <cyassl/ctaocrypt/integer.h>
#include <cyassl/ctaocrypt/error-crypt.h>
#if defined(CYASSL_SHA512) || defined(CYASSL_SHA384)
#include <cyassl/ctaocrypt/sha512.h>
#endif
#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 */
int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
int sLen, int iterations, int kLen, int hashType)
{
Md5 md5;
Sha sha;
int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE;
int i, ret = 0;
byte buffer[SHA_DIGEST_SIZE]; /* max size */
if (hashType != MD5 && hashType != SHA)
return BAD_FUNC_ARG;
if (kLen > hLen)
return BAD_FUNC_ARG;
if (iterations < 1)
return BAD_FUNC_ARG;
if (hashType == MD5) {
InitMd5(&md5);
Md5Update(&md5, passwd, pLen);
Md5Update(&md5, salt, sLen);
Md5Final(&md5, buffer);
}
else {
ret = InitSha(&sha);
if (ret != 0)
return ret;
ShaUpdate(&sha, passwd, pLen);
ShaUpdate(&sha, salt, sLen);
ShaFinal(&sha, buffer);
}
for (i = 1; i < iterations; i++) {
if (hashType == MD5) {
Md5Update(&md5, buffer, hLen);
Md5Final(&md5, buffer);
}
else {
ShaUpdate(&sha, buffer, hLen);
ShaFinal(&sha, buffer);
}
}
XMEMCPY(output, buffer, kLen);
return 0;
}
int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
int sLen, int iterations, int kLen, int hashType)
{
word32 i = 1;
int hLen;
int j, ret;
Hmac hmac;
#ifdef CYASSL_SMALL_STACK
byte* buffer;
#else
byte buffer[MAX_DIGEST_SIZE];
#endif
if (hashType == MD5) {
hLen = MD5_DIGEST_SIZE;
}
else if (hashType == SHA) {
hLen = SHA_DIGEST_SIZE;
}
#ifndef NO_SHA256
else if (hashType == SHA256) {
hLen = SHA256_DIGEST_SIZE;
}
#endif
#ifdef CYASSL_SHA512
else if (hashType == SHA512) {
hLen = SHA512_DIGEST_SIZE;
}
#endif
else
return BAD_FUNC_ARG;
#ifdef CYASSL_SMALL_STACK
buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (buffer == NULL)
return MEMORY_E;
#endif
ret = HmacSetKey(&hmac, hashType, passwd, pLen);
if (ret == 0) {
while (kLen) {
int currentLen;
ret = HmacUpdate(&hmac, salt, sLen);
if (ret != 0)
break;
/* encode i */
for (j = 0; j < 4; j++) {
byte b = (byte)(i >> ((3-j) * 8));
ret = HmacUpdate(&hmac, &b, 1);
if (ret != 0)
break;
}
/* check ret from inside for loop */
if (ret != 0)
break;
ret = HmacFinal(&hmac, buffer);
if (ret != 0)
break;
currentLen = min(kLen, hLen);
XMEMCPY(output, buffer, currentLen);
for (j = 1; j < iterations; j++) {
ret = HmacUpdate(&hmac, buffer, hLen);
if (ret != 0)
break;
ret = HmacFinal(&hmac, buffer);
if (ret != 0)
break;
xorbuf(output, buffer, currentLen);
}
/* check ret from inside for loop */
if (ret != 0)
break;
output += currentLen;
kLen -= currentLen;
i++;
}
}
#ifdef CYASSL_SMALL_STACK
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#ifdef CYASSL_SHA512
#define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE
#elif !defined(NO_SHA256)
#define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE
#else
#define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE
#endif
int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
int saltLen, int iterations, int kLen, int hashType, int id)
{
/* all in bytes instead of bits */
word32 u, v, dLen, pLen, iLen, sLen, totalLen;
int dynamic = 0;
int ret = 0;
int i;
byte *D, *S, *P, *I;
#ifdef CYASSL_SMALL_STACK
byte staticBuffer[1]; /* force dynamic usage */
#else
byte staticBuffer[1024];
#endif
byte* buffer = staticBuffer;
#ifdef CYASSL_SMALL_STACK
byte* Ai;
byte* B;
#else
byte Ai[PBKDF_DIGEST_SIZE];
byte B[PBKDF_DIGEST_SIZE];
#endif
if (!iterations)
iterations = 1;
if (hashType == MD5) {
v = MD5_BLOCK_SIZE;
u = MD5_DIGEST_SIZE;
}
else if (hashType == SHA) {
v = SHA_BLOCK_SIZE;
u = SHA_DIGEST_SIZE;
}
#ifndef NO_SHA256
else if (hashType == SHA256) {
v = SHA256_BLOCK_SIZE;
u = SHA256_DIGEST_SIZE;
}
#endif
#ifdef CYASSL_SHA512
else if (hashType == SHA512) {
v = SHA512_BLOCK_SIZE;
u = SHA512_DIGEST_SIZE;
}
#endif
else
return BAD_FUNC_ARG;
#ifdef CYASSL_SMALL_STACK
Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (Ai == NULL)
return MEMORY_E;
B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (B == NULL) {
XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E;
}
#endif
dLen = v;
sLen = v * ((saltLen + v - 1) / v);
if (passLen)
pLen = v * ((passLen + v - 1) / v);
else
pLen = 0;
iLen = sLen + pLen;
totalLen = dLen + sLen + pLen;
if (totalLen > sizeof(staticBuffer)) {
buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
if (buffer == NULL) {
#ifdef CYASSL_SMALL_STACK
XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MEMORY_E;
}
dynamic = 1;
}
D = buffer;
S = D + dLen;
P = S + sLen;
I = S;
XMEMSET(D, id, dLen);
for (i = 0; i < (int)sLen; i++)
S[i] = salt[i % saltLen];
for (i = 0; i < (int)pLen; i++)
P[i] = passwd[i % passLen];
while (kLen > 0) {
word32 currentLen;
mp_int B1;
if (hashType == MD5) {
Md5 md5;
InitMd5(&md5);
Md5Update(&md5, buffer, totalLen);
Md5Final(&md5, Ai);
for (i = 1; i < iterations; i++) {
Md5Update(&md5, Ai, u);
Md5Final(&md5, Ai);
}
}
else if (hashType == SHA) {
Sha sha;
ret = InitSha(&sha);
if (ret != 0)
break;
ShaUpdate(&sha, buffer, totalLen);
ShaFinal(&sha, Ai);
for (i = 1; i < iterations; i++) {
ShaUpdate(&sha, Ai, u);
ShaFinal(&sha, Ai);
}
}
#ifndef NO_SHA256
else if (hashType == SHA256) {
Sha256 sha256;
ret = InitSha256(&sha256);
if (ret != 0)
break;
ret = Sha256Update(&sha256, buffer, totalLen);
if (ret != 0)
break;
ret = Sha256Final(&sha256, Ai);
if (ret != 0)
break;
for (i = 1; i < iterations; i++) {
ret = Sha256Update(&sha256, Ai, u);
if (ret != 0)
break;
ret = Sha256Final(&sha256, Ai);
if (ret != 0)
break;
}
}
#endif
#ifdef CYASSL_SHA512
else if (hashType == SHA512) {
Sha512 sha512;
ret = InitSha512(&sha512);
if (ret != 0)
break;
ret = Sha512Update(&sha512, buffer, totalLen);
if (ret != 0)
break;
ret = Sha512Final(&sha512, Ai);
if (ret != 0)
break;
for (i = 1; i < iterations; i++) {
ret = Sha512Update(&sha512, Ai, u);
if (ret != 0)
break;
ret = Sha512Final(&sha512, Ai);
if (ret != 0)
break;
}
}
#endif
for (i = 0; i < (int)v; i++)
B[i] = Ai[i % u];
if (mp_init(&B1) != MP_OKAY)
ret = MP_INIT_E;
else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
ret = MP_READ_E;
else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
ret = MP_ADD_E;
if (ret != 0) {
mp_clear(&B1);
break;
}
for (i = 0; i < (int)iLen; i += v) {
int outSz;
mp_int i1;
mp_int res;
if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
ret = MP_INIT_E;
break;
}
if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
ret = MP_READ_E;
else if (mp_add(&i1, &B1, &res) != MP_OKAY)
ret = MP_ADD_E;
else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
ret = MP_TO_E;
else {
if (outSz > (int)v) {
/* take off MSB */
byte tmp[129];
ret = mp_to_unsigned_bin(&res, tmp);
XMEMCPY(I + i, tmp + 1, v);
}
else if (outSz < (int)v) {
XMEMSET(I + i, 0, v - outSz);
ret = mp_to_unsigned_bin(&res, I + i + v - outSz);
}
else
ret = mp_to_unsigned_bin(&res, I + i);
}
mp_clear(&i1);
mp_clear(&res);
if (ret < 0) break;
}
currentLen = min(kLen, (int)u);
XMEMCPY(output, Ai, currentLen);
output += currentLen;
kLen -= currentLen;
mp_clear(&B1);
}
if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
#ifdef CYASSL_SMALL_STACK
XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return ret;
}
#undef PBKDF_DIGEST_SIZE
#endif /* NO_PWDBASED */

310
wolfcrypt/src/rabbit.c Normal file
View File

@@ -0,0 +1,310 @@
/* rabbit.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_RABBIT
#include <cyassl/ctaocrypt/rabbit.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 BIG_ENDIAN_ORDER
#define LITTLE32(x) ByteReverseWord32(x)
#else
#define LITTLE32(x) (x)
#endif
#define U32V(x) ((word32)(x) & 0xFFFFFFFFU)
/* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
/* the upper 32 bits XOR the lower 32 bits */
static word32 RABBIT_g_func(word32 x)
{
/* Temporary variables */
word32 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 = (((U32V(a*a)>>17) + U32V(a*b))>>15) + b*b;
l = x*x;
/* Return high XOR low */
return U32V(h^l);
}
/* Calculate the next internal state */
static void RABBIT_next_state(RabbitCtx* ctx)
{
/* Temporary variables */
word32 g[8], c_old[8], i;
/* Save old counter values */
for (i=0; i<8; i++)
c_old[i] = ctx->c[i];
/* Calculate new counter values */
ctx->c[0] = U32V(ctx->c[0] + 0x4D34D34D + ctx->carry);
ctx->c[1] = U32V(ctx->c[1] + 0xD34D34D3 + (ctx->c[0] < c_old[0]));
ctx->c[2] = U32V(ctx->c[2] + 0x34D34D34 + (ctx->c[1] < c_old[1]));
ctx->c[3] = U32V(ctx->c[3] + 0x4D34D34D + (ctx->c[2] < c_old[2]));
ctx->c[4] = U32V(ctx->c[4] + 0xD34D34D3 + (ctx->c[3] < c_old[3]));
ctx->c[5] = U32V(ctx->c[5] + 0x34D34D34 + (ctx->c[4] < c_old[4]));
ctx->c[6] = U32V(ctx->c[6] + 0x4D34D34D + (ctx->c[5] < c_old[5]));
ctx->c[7] = U32V(ctx->c[7] + 0xD34D34D3 + (ctx->c[6] < c_old[6]));
ctx->carry = (ctx->c[7] < c_old[7]);
/* Calculate the g-values */
for (i=0;i<8;i++)
g[i] = RABBIT_g_func(U32V(ctx->x[i] + ctx->c[i]));
/* Calculate new state values */
ctx->x[0] = U32V(g[0] + rotlFixed(g[7],16) + rotlFixed(g[6], 16));
ctx->x[1] = U32V(g[1] + rotlFixed(g[0], 8) + g[7]);
ctx->x[2] = U32V(g[2] + rotlFixed(g[1],16) + rotlFixed(g[0], 16));
ctx->x[3] = U32V(g[3] + rotlFixed(g[2], 8) + g[1]);
ctx->x[4] = U32V(g[4] + rotlFixed(g[3],16) + rotlFixed(g[2], 16));
ctx->x[5] = U32V(g[5] + rotlFixed(g[4], 8) + g[3]);
ctx->x[6] = U32V(g[6] + rotlFixed(g[5],16) + rotlFixed(g[4], 16));
ctx->x[7] = U32V(g[7] + rotlFixed(g[6], 8) + g[5]);
}
/* IV setup */
static void RabbitSetIV(Rabbit* ctx, const byte* inIv)
{
/* Temporary variables */
word32 i0, i1, i2, i3, i;
word32 iv[2];
if (inIv)
XMEMCPY(iv, inIv, sizeof(iv));
else
XMEMSET(iv, 0, sizeof(iv));
/* Generate four subvectors */
i0 = LITTLE32(iv[0]);
i2 = LITTLE32(iv[1]);
i1 = (i0>>16) | (i2&0xFFFF0000);
i3 = (i2<<16) | (i0&0x0000FFFF);
/* Modify counter values */
ctx->workCtx.c[0] = ctx->masterCtx.c[0] ^ i0;
ctx->workCtx.c[1] = ctx->masterCtx.c[1] ^ i1;
ctx->workCtx.c[2] = ctx->masterCtx.c[2] ^ i2;
ctx->workCtx.c[3] = ctx->masterCtx.c[3] ^ i3;
ctx->workCtx.c[4] = ctx->masterCtx.c[4] ^ i0;
ctx->workCtx.c[5] = ctx->masterCtx.c[5] ^ i1;
ctx->workCtx.c[6] = ctx->masterCtx.c[6] ^ i2;
ctx->workCtx.c[7] = ctx->masterCtx.c[7] ^ i3;
/* Copy state variables */
for (i=0; i<8; i++)
ctx->workCtx.x[i] = ctx->masterCtx.x[i];
ctx->workCtx.carry = ctx->masterCtx.carry;
/* Iterate the system four times */
for (i=0; i<4; i++)
RABBIT_next_state(&(ctx->workCtx));
}
/* Key setup */
static INLINE int DoKey(Rabbit* ctx, const byte* key, const byte* iv)
{
/* Temporary variables */
word32 k0, k1, k2, k3, i;
/* Generate four subkeys */
k0 = LITTLE32(*(word32*)(key+ 0));
k1 = LITTLE32(*(word32*)(key+ 4));
k2 = LITTLE32(*(word32*)(key+ 8));
k3 = LITTLE32(*(word32*)(key+12));
/* Generate initial state variables */
ctx->masterCtx.x[0] = k0;
ctx->masterCtx.x[2] = k1;
ctx->masterCtx.x[4] = k2;
ctx->masterCtx.x[6] = k3;
ctx->masterCtx.x[1] = U32V(k3<<16) | (k2>>16);
ctx->masterCtx.x[3] = U32V(k0<<16) | (k3>>16);
ctx->masterCtx.x[5] = U32V(k1<<16) | (k0>>16);
ctx->masterCtx.x[7] = U32V(k2<<16) | (k1>>16);
/* Generate initial counter values */
ctx->masterCtx.c[0] = rotlFixed(k2, 16);
ctx->masterCtx.c[2] = rotlFixed(k3, 16);
ctx->masterCtx.c[4] = rotlFixed(k0, 16);
ctx->masterCtx.c[6] = rotlFixed(k1, 16);
ctx->masterCtx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
ctx->masterCtx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
ctx->masterCtx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
ctx->masterCtx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
/* Clear carry bit */
ctx->masterCtx.carry = 0;
/* Iterate the system four times */
for (i=0; i<4; i++)
RABBIT_next_state(&(ctx->masterCtx));
/* Modify the counters */
for (i=0; i<8; i++)
ctx->masterCtx.c[i] ^= ctx->masterCtx.x[(i+4)&0x7];
/* Copy master instance to work instance */
for (i=0; i<8; i++) {
ctx->workCtx.x[i] = ctx->masterCtx.x[i];
ctx->workCtx.c[i] = ctx->masterCtx.c[i];
}
ctx->workCtx.carry = ctx->masterCtx.carry;
RabbitSetIV(ctx, iv);
return 0;
}
/* Key setup */
int wc_RabbitSetKey(Rabbit* ctx, const byte* key, const byte* iv)
{
#ifdef XSTREAM_ALIGN
if ((cyassl_word)key % 4) {
int alignKey[4];
/* iv aligned in SetIV */
WOLFSSL_MSG("wc_RabbitSetKey unaligned key");
XMEMCPY(alignKey, key, sizeof(alignKey));
return DoKey(ctx, (const byte*)alignKey, iv);
}
#endif /* XSTREAM_ALIGN */
return DoKey(ctx, key, iv);
}
/* Encrypt/decrypt a message of any size */
static INLINE int DoProcess(Rabbit* ctx, byte* output, const byte* input,
word32 msglen)
{
/* Encrypt/decrypt all full blocks */
while (msglen >= 16) {
/* Iterate the system */
RABBIT_next_state(&(ctx->workCtx));
/* Encrypt/decrypt 16 bytes of data */
*(word32*)(output+ 0) = *(word32*)(input+ 0) ^
LITTLE32(ctx->workCtx.x[0] ^ (ctx->workCtx.x[5]>>16) ^
U32V(ctx->workCtx.x[3]<<16));
*(word32*)(output+ 4) = *(word32*)(input+ 4) ^
LITTLE32(ctx->workCtx.x[2] ^ (ctx->workCtx.x[7]>>16) ^
U32V(ctx->workCtx.x[5]<<16));
*(word32*)(output+ 8) = *(word32*)(input+ 8) ^
LITTLE32(ctx->workCtx.x[4] ^ (ctx->workCtx.x[1]>>16) ^
U32V(ctx->workCtx.x[7]<<16));
*(word32*)(output+12) = *(word32*)(input+12) ^
LITTLE32(ctx->workCtx.x[6] ^ (ctx->workCtx.x[3]>>16) ^
U32V(ctx->workCtx.x[1]<<16));
/* Increment pointers and decrement length */
input += 16;
output += 16;
msglen -= 16;
}
/* Encrypt/decrypt remaining data */
if (msglen) {
word32 i;
word32 tmp[4];
byte* buffer = (byte*)tmp;
XMEMSET(tmp, 0, sizeof(tmp)); /* help static analysis */
/* Iterate the system */
RABBIT_next_state(&(ctx->workCtx));
/* Generate 16 bytes of pseudo-random data */
tmp[0] = LITTLE32(ctx->workCtx.x[0] ^
(ctx->workCtx.x[5]>>16) ^ U32V(ctx->workCtx.x[3]<<16));
tmp[1] = LITTLE32(ctx->workCtx.x[2] ^
(ctx->workCtx.x[7]>>16) ^ U32V(ctx->workCtx.x[5]<<16));
tmp[2] = LITTLE32(ctx->workCtx.x[4] ^
(ctx->workCtx.x[1]>>16) ^ U32V(ctx->workCtx.x[7]<<16));
tmp[3] = LITTLE32(ctx->workCtx.x[6] ^
(ctx->workCtx.x[3]>>16) ^ U32V(ctx->workCtx.x[1]<<16));
/* Encrypt/decrypt the data */
for (i=0; i<msglen; i++)
output[i] = input[i] ^ buffer[i];
}
return 0;
}
/* Encrypt/decrypt a message of any size */
int wc_RabbitProcess(Rabbit* ctx, byte* output, const byte* input, word32 msglen)
{
#ifdef XSTREAM_ALIGN
if ((cyassl_word)input % 4 || (cyassl_word)output % 4) {
#ifndef NO_WOLFSSL_ALLOC_ALIGN
byte* tmp;
WOLFSSL_MSG("wc_RabbitProcess unaligned");
tmp = (byte*)XMALLOC(msglen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (tmp == NULL) return MEMORY_E;
XMEMCPY(tmp, input, msglen);
DoProcess(ctx, tmp, tmp, msglen);
XMEMCPY(output, tmp, msglen);
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return 0;
#else
return BAD_ALIGN_E;
#endif
}
#endif /* XSTREAM_ALIGN */
return DoProcess(ctx, output, input, msglen);
}
#endif /* NO_RABBIT */

354
wolfcrypt/src/ripemd.c Normal file
View File

@@ -0,0 +1,354 @@
/* 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 WOLFSSL_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 wc_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 wc_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 wc_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);
wc_InitRipeMd(ripemd); /* reset state */
}
#endif /* WOLFSSL_RIPEMD */