mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 04:34:41 +02:00
c files for pkcs, poly, rabbit and ripemd
This commit is contained in:
49
cyassl/ssl.h
49
cyassl/ssl.h
@@ -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
1849
wolfcrypt/src/pkcs7.c
Normal file
File diff suppressed because it is too large
Load Diff
554
wolfcrypt/src/poly1305.c
Normal file
554
wolfcrypt/src/poly1305.c
Normal 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
474
wolfcrypt/src/pwdbased.c
Normal 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
310
wolfcrypt/src/rabbit.c
Normal 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
354
wolfcrypt/src/ripemd.c
Normal 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 */
|
Reference in New Issue
Block a user