You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
parent
ee1447783b
commit
94b2861243
33
external/boringssl/crypto/poly1305/CMakeLists.txt
vendored
Normal file
33
external/boringssl/crypto/poly1305/CMakeLists.txt
vendored
Normal 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()
|
||||
1216
external/boringssl/crypto/poly1305/asm/poly1305-armv4.pl
vendored
Executable file
1216
external/boringssl/crypto/poly1305/asm/poly1305-armv4.pl
vendored
Executable file
File diff suppressed because it is too large
Load Diff
925
external/boringssl/crypto/poly1305/asm/poly1305-armv8.pl
vendored
Executable file
925
external/boringssl/crypto/poly1305/asm/poly1305-armv8.pl
vendored
Executable file
File diff suppressed because it is too large
Load Diff
1788
external/boringssl/crypto/poly1305/asm/poly1305-x86.pl
vendored
Executable file
1788
external/boringssl/crypto/poly1305/asm/poly1305-x86.pl
vendored
Executable file
File diff suppressed because it is too large
Load Diff
2235
external/boringssl/crypto/poly1305/asm/poly1305-x86_64.pl
vendored
Executable file
2235
external/boringssl/crypto/poly1305/asm/poly1305-x86_64.pl
vendored
Executable file
File diff suppressed because it is too large
Load Diff
40
external/boringssl/crypto/poly1305/internal.h
vendored
Normal file
40
external/boringssl/crypto/poly1305/internal.h
vendored
Normal 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 */
|
||||
324
external/boringssl/crypto/poly1305/poly1305.c
vendored
Normal file
324
external/boringssl/crypto/poly1305/poly1305.c
vendored
Normal 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 */
|
||||
304
external/boringssl/crypto/poly1305/poly1305_arm.c
vendored
Normal file
304
external/boringssl/crypto/poly1305/poly1305_arm.c
vendored
Normal 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 */
|
||||
2015
external/boringssl/crypto/poly1305/poly1305_arm_asm.S
vendored
Normal file
2015
external/boringssl/crypto/poly1305/poly1305_arm_asm.S
vendored
Normal file
File diff suppressed because it is too large
Load Diff
131
external/boringssl/crypto/poly1305/poly1305_test.cc
vendored
Normal file
131
external/boringssl/crypto/poly1305/poly1305_test.cc
vendored
Normal 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]);
|
||||
}
|
||||
159
external/boringssl/crypto/poly1305/poly1305_tests.txt
vendored
Normal file
159
external/boringssl/crypto/poly1305/poly1305_tests.txt
vendored
Normal file
File diff suppressed because one or more lines are too long
890
external/boringssl/crypto/poly1305/poly1305_vec.c
vendored
Normal file
890
external/boringssl/crypto/poly1305/poly1305_vec.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user