Imported Upstream version 4.8.0.309

Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-11-10 13:04:39 +00:00
parent ee1447783b
commit 94b2861243
4912 changed files with 390737 additions and 49310 deletions

View File

@@ -0,0 +1,33 @@
include_directories(../../include)
if (${ARCH} STREQUAL "arm")
set(
POLY1305_ARCH_SOURCES
poly1305_arm_asm.S
)
endif()
add_library(
poly1305
OBJECT
poly1305.c
poly1305_arm.c
poly1305_vec.c
${POLY1305_ARCH_SOURCES}
)
if(ENABLE_TESTS)
add_executable(
poly1305_test
poly1305_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(poly1305_test crypto)
add_dependencies(all_tests poly1305_test)
endif()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef OPENSSL_HEADER_POLY1305_INTERNAL_H
#define OPENSSL_HEADER_POLY1305_INTERNAL_H
#include <openssl/base.h>
#include <openssl/poly1305.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]);
void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in,
size_t in_len);
void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]);
#endif
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_POLY1305_INTERNAL_H */

View File

@@ -0,0 +1,324 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/* This implementation of poly1305 is by Andrew Moon
* (https://github.com/floodyberry/poly1305-donna) and released as public
* domain. */
#include <openssl/poly1305.h>
#include <string.h>
#include <openssl/cpu.h>
#include "internal.h"
#if defined(OPENSSL_WINDOWS) || !defined(OPENSSL_X86_64)
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM)
/* We can assume little-endian. */
static uint32_t U8TO32_LE(const uint8_t *m) {
uint32_t r;
memcpy(&r, m, sizeof(r));
return r;
}
static void U32TO8_LE(uint8_t *m, uint32_t v) { memcpy(m, &v, sizeof(v)); }
#else
static uint32_t U8TO32_LE(const uint8_t *m) {
return (uint32_t)m[0] | (uint32_t)m[1] << 8 | (uint32_t)m[2] << 16 |
(uint32_t)m[3] << 24;
}
static void U32TO8_LE(uint8_t *m, uint32_t v) {
m[0] = v;
m[1] = v >> 8;
m[2] = v >> 16;
m[3] = v >> 24;
}
#endif
static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; }
struct poly1305_state_st {
uint32_t r0, r1, r2, r3, r4;
uint32_t s1, s2, s3, s4;
uint32_t h0, h1, h2, h3, h4;
uint8_t buf[16];
unsigned int buf_used;
uint8_t key[16];
};
/* poly1305_blocks updates |state| given some amount of input data. This
* function may only be called with a |len| that is not a multiple of 16 at the
* end of the data. Otherwise the input must be buffered into 16 byte blocks. */
static void poly1305_update(struct poly1305_state_st *state, const uint8_t *in,
size_t len) {
uint32_t t0, t1, t2, t3;
uint64_t t[5];
uint32_t b;
uint64_t c;
size_t j;
uint8_t mp[16];
if (len < 16) {
goto poly1305_donna_atmost15bytes;
}
poly1305_donna_16bytes:
t0 = U8TO32_LE(in);
t1 = U8TO32_LE(in + 4);
t2 = U8TO32_LE(in + 8);
t3 = U8TO32_LE(in + 12);
in += 16;
len -= 16;
state->h0 += t0 & 0x3ffffff;
state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
state->h4 += (t3 >> 8) | (1 << 24);
poly1305_donna_mul:
t[0] = mul32x32_64(state->h0, state->r0) + mul32x32_64(state->h1, state->s4) +
mul32x32_64(state->h2, state->s3) + mul32x32_64(state->h3, state->s2) +
mul32x32_64(state->h4, state->s1);
t[1] = mul32x32_64(state->h0, state->r1) + mul32x32_64(state->h1, state->r0) +
mul32x32_64(state->h2, state->s4) + mul32x32_64(state->h3, state->s3) +
mul32x32_64(state->h4, state->s2);
t[2] = mul32x32_64(state->h0, state->r2) + mul32x32_64(state->h1, state->r1) +
mul32x32_64(state->h2, state->r0) + mul32x32_64(state->h3, state->s4) +
mul32x32_64(state->h4, state->s3);
t[3] = mul32x32_64(state->h0, state->r3) + mul32x32_64(state->h1, state->r2) +
mul32x32_64(state->h2, state->r1) + mul32x32_64(state->h3, state->r0) +
mul32x32_64(state->h4, state->s4);
t[4] = mul32x32_64(state->h0, state->r4) + mul32x32_64(state->h1, state->r3) +
mul32x32_64(state->h2, state->r2) + mul32x32_64(state->h3, state->r1) +
mul32x32_64(state->h4, state->r0);
state->h0 = (uint32_t)t[0] & 0x3ffffff;
c = (t[0] >> 26);
t[1] += c;
state->h1 = (uint32_t)t[1] & 0x3ffffff;
b = (uint32_t)(t[1] >> 26);
t[2] += b;
state->h2 = (uint32_t)t[2] & 0x3ffffff;
b = (uint32_t)(t[2] >> 26);
t[3] += b;
state->h3 = (uint32_t)t[3] & 0x3ffffff;
b = (uint32_t)(t[3] >> 26);
t[4] += b;
state->h4 = (uint32_t)t[4] & 0x3ffffff;
b = (uint32_t)(t[4] >> 26);
state->h0 += b * 5;
if (len >= 16) {
goto poly1305_donna_16bytes;
}
/* final bytes */
poly1305_donna_atmost15bytes:
if (!len) {
return;
}
for (j = 0; j < len; j++) {
mp[j] = in[j];
}
mp[j++] = 1;
for (; j < 16; j++) {
mp[j] = 0;
}
len = 0;
t0 = U8TO32_LE(mp + 0);
t1 = U8TO32_LE(mp + 4);
t2 = U8TO32_LE(mp + 8);
t3 = U8TO32_LE(mp + 12);
state->h0 += t0 & 0x3ffffff;
state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
state->h4 += (t3 >> 8);
goto poly1305_donna_mul;
}
void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) {
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
uint32_t t0, t1, t2, t3;
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
if (CRYPTO_is_NEON_capable()) {
CRYPTO_poly1305_init_neon(statep, key);
return;
}
#endif
t0 = U8TO32_LE(key + 0);
t1 = U8TO32_LE(key + 4);
t2 = U8TO32_LE(key + 8);
t3 = U8TO32_LE(key + 12);
/* precompute multipliers */
state->r0 = t0 & 0x3ffffff;
t0 >>= 26;
t0 |= t1 << 6;
state->r1 = t0 & 0x3ffff03;
t1 >>= 20;
t1 |= t2 << 12;
state->r2 = t1 & 0x3ffc0ff;
t2 >>= 14;
t2 |= t3 << 18;
state->r3 = t2 & 0x3f03fff;
t3 >>= 8;
state->r4 = t3 & 0x00fffff;
state->s1 = state->r1 * 5;
state->s2 = state->r2 * 5;
state->s3 = state->r3 * 5;
state->s4 = state->r4 * 5;
/* init state */
state->h0 = 0;
state->h1 = 0;
state->h2 = 0;
state->h3 = 0;
state->h4 = 0;
state->buf_used = 0;
memcpy(state->key, key + 16, sizeof(state->key));
}
void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in,
size_t in_len) {
unsigned int i;
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
if (CRYPTO_is_NEON_capable()) {
CRYPTO_poly1305_update_neon(statep, in, in_len);
return;
}
#endif
if (state->buf_used) {
unsigned int todo = 16 - state->buf_used;
if (todo > in_len) {
todo = in_len;
}
for (i = 0; i < todo; i++) {
state->buf[state->buf_used + i] = in[i];
}
state->buf_used += todo;
in_len -= todo;
in += todo;
if (state->buf_used == 16) {
poly1305_update(state, state->buf, 16);
state->buf_used = 0;
}
}
if (in_len >= 16) {
size_t todo = in_len & ~0xf;
poly1305_update(state, in, todo);
in += todo;
in_len &= 0xf;
}
if (in_len) {
for (i = 0; i < in_len; i++) {
state->buf[i] = in[i];
}
state->buf_used = in_len;
}
}
void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) {
struct poly1305_state_st *state = (struct poly1305_state_st *)statep;
uint64_t f0, f1, f2, f3;
uint32_t g0, g1, g2, g3, g4;
uint32_t b, nb;
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
if (CRYPTO_is_NEON_capable()) {
CRYPTO_poly1305_finish_neon(statep, mac);
return;
}
#endif
if (state->buf_used) {
poly1305_update(state, state->buf, state->buf_used);
}
b = state->h0 >> 26;
state->h0 = state->h0 & 0x3ffffff;
state->h1 += b;
b = state->h1 >> 26;
state->h1 = state->h1 & 0x3ffffff;
state->h2 += b;
b = state->h2 >> 26;
state->h2 = state->h2 & 0x3ffffff;
state->h3 += b;
b = state->h3 >> 26;
state->h3 = state->h3 & 0x3ffffff;
state->h4 += b;
b = state->h4 >> 26;
state->h4 = state->h4 & 0x3ffffff;
state->h0 += b * 5;
g0 = state->h0 + 5;
b = g0 >> 26;
g0 &= 0x3ffffff;
g1 = state->h1 + b;
b = g1 >> 26;
g1 &= 0x3ffffff;
g2 = state->h2 + b;
b = g2 >> 26;
g2 &= 0x3ffffff;
g3 = state->h3 + b;
b = g3 >> 26;
g3 &= 0x3ffffff;
g4 = state->h4 + b - (1 << 26);
b = (g4 >> 31) - 1;
nb = ~b;
state->h0 = (state->h0 & nb) | (g0 & b);
state->h1 = (state->h1 & nb) | (g1 & b);
state->h2 = (state->h2 & nb) | (g2 & b);
state->h3 = (state->h3 & nb) | (g3 & b);
state->h4 = (state->h4 & nb) | (g4 & b);
f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]);
f1 = ((state->h1 >> 6) | (state->h2 << 20)) +
(uint64_t)U8TO32_LE(&state->key[4]);
f2 = ((state->h2 >> 12) | (state->h3 << 14)) +
(uint64_t)U8TO32_LE(&state->key[8]);
f3 = ((state->h3 >> 18) | (state->h4 << 8)) +
(uint64_t)U8TO32_LE(&state->key[12]);
U32TO8_LE(&mac[0], f0);
f1 += (f0 >> 32);
U32TO8_LE(&mac[4], f1);
f2 += (f1 >> 32);
U32TO8_LE(&mac[8], f2);
f3 += (f2 >> 32);
U32TO8_LE(&mac[12], f3);
}
#endif /* OPENSSL_WINDOWS || !OPENSSL_X86_64 */

View File

@@ -0,0 +1,304 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/* This implementation was taken from the public domain, neon2 version in
* SUPERCOP by D. J. Bernstein and Peter Schwabe. */
#include <openssl/poly1305.h>
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
#include <string.h>
#include "../internal.h"
#include "internal.h"
typedef struct {
uint32_t v[12]; /* for alignment; only using 10 */
} fe1305x2;
#define addmulmod openssl_poly1305_neon2_addmulmod
#define blocks openssl_poly1305_neon2_blocks
extern void addmulmod(fe1305x2 *r, const fe1305x2 *x, const fe1305x2 *y,
const fe1305x2 *c);
extern int blocks(fe1305x2 *h, const fe1305x2 *precomp, const uint8_t *in,
unsigned int inlen);
static void freeze(fe1305x2 *r) {
int i;
uint32_t x0 = r->v[0];
uint32_t x1 = r->v[2];
uint32_t x2 = r->v[4];
uint32_t x3 = r->v[6];
uint32_t x4 = r->v[8];
uint32_t y0;
uint32_t y1;
uint32_t y2;
uint32_t y3;
uint32_t y4;
uint32_t swap;
for (i = 0; i < 3; ++i) {
x1 += x0 >> 26;
x0 &= 0x3ffffff;
x2 += x1 >> 26;
x1 &= 0x3ffffff;
x3 += x2 >> 26;
x2 &= 0x3ffffff;
x4 += x3 >> 26;
x3 &= 0x3ffffff;
x0 += 5 * (x4 >> 26);
x4 &= 0x3ffffff;
}
y0 = x0 + 5;
y1 = x1 + (y0 >> 26);
y0 &= 0x3ffffff;
y2 = x2 + (y1 >> 26);
y1 &= 0x3ffffff;
y3 = x3 + (y2 >> 26);
y2 &= 0x3ffffff;
y4 = x4 + (y3 >> 26);
y3 &= 0x3ffffff;
swap = -(y4 >> 26);
y4 &= 0x3ffffff;
y0 ^= x0;
y1 ^= x1;
y2 ^= x2;
y3 ^= x3;
y4 ^= x4;
y0 &= swap;
y1 &= swap;
y2 &= swap;
y3 &= swap;
y4 &= swap;
y0 ^= x0;
y1 ^= x1;
y2 ^= x2;
y3 ^= x3;
y4 ^= x4;
r->v[0] = y0;
r->v[2] = y1;
r->v[4] = y2;
r->v[6] = y3;
r->v[8] = y4;
}
static void fe1305x2_tobytearray(uint8_t *r, fe1305x2 *x) {
uint32_t x0 = x->v[0];
uint32_t x1 = x->v[2];
uint32_t x2 = x->v[4];
uint32_t x3 = x->v[6];
uint32_t x4 = x->v[8];
x1 += x0 >> 26;
x0 &= 0x3ffffff;
x2 += x1 >> 26;
x1 &= 0x3ffffff;
x3 += x2 >> 26;
x2 &= 0x3ffffff;
x4 += x3 >> 26;
x3 &= 0x3ffffff;
*(uint32_t *)r = x0 + (x1 << 26);
*(uint32_t *)(r + 4) = (x1 >> 6) + (x2 << 20);
*(uint32_t *)(r + 8) = (x2 >> 12) + (x3 << 14);
*(uint32_t *)(r + 12) = (x3 >> 18) + (x4 << 8);
}
/* load32 exists to avoid breaking strict aliasing rules in
* fe1305x2_frombytearray. */
static uint32_t load32(uint8_t *t) {
uint32_t tmp;
memcpy(&tmp, t, sizeof(tmp));
return tmp;
}
static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x,
unsigned long long xlen) {
unsigned i;
uint8_t t[17];
for (i = 0; (i < 16) && (i < xlen); i++) {
t[i] = x[i];
}
xlen -= i;
x += i;
t[i++] = 1;
for (; i < 17; i++) {
t[i] = 0;
}
r->v[0] = 0x3ffffff & load32(t);
r->v[2] = 0x3ffffff & (load32(t + 3) >> 2);
r->v[4] = 0x3ffffff & (load32(t + 6) >> 4);
r->v[6] = 0x3ffffff & (load32(t + 9) >> 6);
r->v[8] = load32(t + 13);
if (xlen) {
for (i = 0; (i < 16) && (i < xlen); i++) {
t[i] = x[i];
}
t[i++] = 1;
for (; i < 17; i++) {
t[i] = 0;
}
r->v[1] = 0x3ffffff & load32(t);
r->v[3] = 0x3ffffff & (load32(t + 3) >> 2);
r->v[5] = 0x3ffffff & (load32(t + 6) >> 4);
r->v[7] = 0x3ffffff & (load32(t + 9) >> 6);
r->v[9] = load32(t + 13);
} else {
r->v[1] = r->v[3] = r->v[5] = r->v[7] = r->v[9] = 0;
}
}
static const alignas(16) fe1305x2 zero;
struct poly1305_state_st {
uint8_t data[sizeof(fe1305x2[5]) + 128];
uint8_t buf[32];
unsigned int buf_used;
uint8_t key[16];
};
void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]) {
struct poly1305_state_st *st = (struct poly1305_state_st *)(state);
fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data)));
fe1305x2 *const h = r + 1;
fe1305x2 *const c = h + 1;
fe1305x2 *const precomp = c + 1;
unsigned int j;
r->v[1] = r->v[0] = 0x3ffffff & *(uint32_t *)key;
r->v[3] = r->v[2] = 0x3ffff03 & ((*(uint32_t *)(key + 3)) >> 2);
r->v[5] = r->v[4] = 0x3ffc0ff & ((*(uint32_t *)(key + 6)) >> 4);
r->v[7] = r->v[6] = 0x3f03fff & ((*(uint32_t *)(key + 9)) >> 6);
r->v[9] = r->v[8] = 0x00fffff & ((*(uint32_t *)(key + 12)) >> 8);
for (j = 0; j < 10; j++) {
h->v[j] = 0; /* XXX: should fast-forward a bit */
}
addmulmod(precomp, r, r, &zero); /* precompute r^2 */
addmulmod(precomp + 1, precomp, precomp, &zero); /* precompute r^4 */
memcpy(st->key, key + 16, 16);
st->buf_used = 0;
}
void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in,
size_t in_len) {
struct poly1305_state_st *st = (struct poly1305_state_st *)(state);
fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data)));
fe1305x2 *const h = r + 1;
fe1305x2 *const c = h + 1;
fe1305x2 *const precomp = c + 1;
unsigned int i;
if (st->buf_used) {
unsigned int todo = 32 - st->buf_used;
if (todo > in_len) {
todo = in_len;
}
for (i = 0; i < todo; i++) {
st->buf[st->buf_used + i] = in[i];
}
st->buf_used += todo;
in_len -= todo;
in += todo;
if (st->buf_used == sizeof(st->buf) && in_len) {
addmulmod(h, h, precomp, &zero);
fe1305x2_frombytearray(c, st->buf, sizeof(st->buf));
for (i = 0; i < 10; i++) {
h->v[i] += c->v[i];
}
st->buf_used = 0;
}
}
while (in_len > 32) {
unsigned int tlen = 1048576;
if (in_len < tlen) {
tlen = in_len;
}
tlen -= blocks(h, precomp, in, tlen);
in_len -= tlen;
in += tlen;
}
if (in_len) {
for (i = 0; i < in_len; i++) {
st->buf[i] = in[i];
}
st->buf_used = in_len;
}
}
void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]) {
struct poly1305_state_st *st = (struct poly1305_state_st *)(state);
fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data)));
fe1305x2 *const h = r + 1;
fe1305x2 *const c = h + 1;
fe1305x2 *const precomp = c + 1;
addmulmod(h, h, precomp, &zero);
if (st->buf_used > 16) {
fe1305x2_frombytearray(c, st->buf, st->buf_used);
precomp->v[1] = r->v[1];
precomp->v[3] = r->v[3];
precomp->v[5] = r->v[5];
precomp->v[7] = r->v[7];
precomp->v[9] = r->v[9];
addmulmod(h, h, precomp, c);
} else if (st->buf_used > 0) {
fe1305x2_frombytearray(c, st->buf, st->buf_used);
r->v[1] = 1;
r->v[3] = 0;
r->v[5] = 0;
r->v[7] = 0;
r->v[9] = 0;
addmulmod(h, h, r, c);
}
h->v[0] += h->v[1];
h->v[2] += h->v[3];
h->v[4] += h->v[5];
h->v[6] += h->v[7];
h->v[8] += h->v[9];
freeze(h);
fe1305x2_frombytearray(c, st->key, 16);
c->v[8] ^= (1 << 24);
h->v[0] += c->v[0];
h->v[2] += c->v[2];
h->v[4] += c->v[4];
h->v[6] += c->v[6];
h->v[8] += c->v[8];
fe1305x2_tobytearray(mac, h);
}
#endif /* OPENSSL_ARM && !OPENSSL_NO_ASM */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <stdio.h>
#include <string.h>
#include <vector>
#include <openssl/crypto.h>
#include <openssl/poly1305.h>
#include "../internal.h"
#include "../test/file_test.h"
static bool TestSIMD(FileTest *t, unsigned excess,
const std::vector<uint8_t> &key,
const std::vector<uint8_t> &in,
const std::vector<uint8_t> &mac) {
poly1305_state state;
CRYPTO_poly1305_init(&state, key.data());
size_t done = 0;
// Feed 16 bytes in. Some implementations begin in non-SIMD mode and upgrade
// on-demand. Stress the upgrade path.
size_t todo = 16;
if (todo > in.size()) {
todo = in.size();
}
CRYPTO_poly1305_update(&state, in.data(), todo);
done += todo;
for (;;) {
// Feed 128 + |excess| bytes to test SIMD mode.
if (done + 128 + excess > in.size()) {
break;
}
CRYPTO_poly1305_update(&state, in.data() + done, 128 + excess);
done += 128 + excess;
// Feed |excess| bytes to ensure SIMD mode can handle short inputs.
if (done + excess > in.size()) {
break;
}
CRYPTO_poly1305_update(&state, in.data() + done, excess);
done += excess;
}
// Consume the remainder and finish.
CRYPTO_poly1305_update(&state, in.data() + done, in.size() - done);
// |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
alignas(16) uint8_t out[16];
CRYPTO_poly1305_finish(&state, out);
if (!t->ExpectBytesEqual(mac.data(), mac.size(), out, 16)) {
t->PrintLine("SIMD pattern %u failed.", excess);
return false;
}
return true;
}
static bool TestPoly1305(FileTest *t, void *arg) {
std::vector<uint8_t> key, in, mac;
if (!t->GetBytes(&key, "Key") ||
!t->GetBytes(&in, "Input") ||
!t->GetBytes(&mac, "MAC")) {
return false;
}
if (key.size() != 32 || mac.size() != 16) {
t->PrintLine("Invalid test");
return false;
}
// Test single-shot operation.
poly1305_state state;
CRYPTO_poly1305_init(&state, key.data());
CRYPTO_poly1305_update(&state, in.data(), in.size());
// |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
alignas(16) uint8_t out[16];
CRYPTO_poly1305_finish(&state, out);
if (!t->ExpectBytesEqual(out, 16, mac.data(), mac.size())) {
t->PrintLine("Single-shot Poly1305 failed.");
return false;
}
// Test streaming byte-by-byte.
CRYPTO_poly1305_init(&state, key.data());
for (size_t i = 0; i < in.size(); i++) {
CRYPTO_poly1305_update(&state, &in[i], 1);
}
CRYPTO_poly1305_finish(&state, out);
if (!t->ExpectBytesEqual(mac.data(), mac.size(), out, 16)) {
t->PrintLine("Streaming Poly1305 failed.");
return false;
}
// Test SIMD stress patterns. OpenSSL's AVX2 assembly needs a multiple of
// four blocks, so test up to three blocks of excess.
if (!TestSIMD(t, 0, key, in, mac) ||
!TestSIMD(t, 16, key, in, mac) ||
!TestSIMD(t, 32, key, in, mac) ||
!TestSIMD(t, 48, key, in, mac)) {
return false;
}
return true;
}
int main(int argc, char **argv) {
CRYPTO_library_init();
if (argc != 2) {
fprintf(stderr, "%s <test file>\n", argv[0]);
return 1;
}
return FileTestMain(TestPoly1305, nullptr, argv[1]);
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff