Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 907ae62b9d | |||
| 65be20fe2f | |||
| ab441a3a39 | |||
| afe57cb14d | |||
| 77c3c0b025 | |||
| 9f897b2580 | |||
| 1741a9d143 | |||
| df571631cc | |||
| 13414b3a04 | |||
| 37489902ba | |||
| 2089fdd10e | |||
| 86e412dc18 | |||
| 23a681b9f9 | |||
| e3203923b5 | |||
| 8ffab72683 | |||
| fef6fb592b | |||
| 60a08ac211 | |||
| 4ec0cce743 | |||
| 2936170d68 | |||
| a01deee96b | |||
| 77385bb43d | |||
| 6969971fef | |||
| 1b36716ce2 | |||
| 017231a544 | |||
| 793c21e266 | |||
| 0aff3ffb88 | |||
| 5a19d7dfa8 | |||
| 78fefbf3bb | |||
| fea1137e55 | |||
| 871fff076b | |||
| d9f0671bbe | |||
| cd480380fa | |||
| 7fc010014c | |||
| ece5ba2797 | |||
| a41280d8cb | |||
| 8fd5c23218 | |||
| ef5dfd2980 | |||
| 8411b248c3 | |||
| 502a843dee | |||
| c3ae38b4f8 | |||
| 7100ee9832 | |||
| f28dd64d43 | |||
| 423488557c | |||
| 45dab251f3 | |||
| 8a58933db0 | |||
| 0abd6f2eb6 | |||
| 1246670caa | |||
| 5ddffbb8bc | |||
| 53e5c2c225 | |||
| 756ad17337 | |||
| 1634a33495 | |||
| b36a395a9a | |||
| 0bd71eb85d | |||
| e9cddb8879 | |||
| 3e052de5a0 | |||
| 03f000577f | |||
| ef5e515819 | |||
| c100ef4379 | |||
| 2205093e7e | |||
| 6ae67dfee8 | |||
| a0ef7b0a56 | |||
| 533a273871 | |||
| a3d9de05fb | |||
| 88478562a4 | |||
| dca63cfa75 | |||
| afd565ff9c | |||
| 902870e3b5 | |||
| 34aa55c05e | |||
| 6d9e5a7448 | |||
| 28243c08db | |||
| e701f16bd6 | |||
| cb852981cd | |||
| c4f25ce0c6 | |||
| c5eb4676b6 | |||
| 758d12732a | |||
| fde89b43c3 | |||
| 60a45aa7cc | |||
| 81edc9beb6 | |||
| e8fe07fcc4 | |||
| 93a5b44296 | |||
| bf762186c6 | |||
| 596ab10b0f | |||
| 7af36e1e38 | |||
| ff2df337a0 | |||
| 9f2e2770e1 | |||
| d6e9eec3f8 | |||
| dcb6ef0f0b | |||
| d28f59c27b | |||
| fba735cfd8 | |||
| f3376ace43 | |||
| 301efc8cea | |||
| e2136d9c28 | |||
| 9b26297608 | |||
| 5058d79948 | |||
| b1b6229fc8 | |||
| 9e65d487b8 | |||
| 3ac32b1eda | |||
| 4fb0dc4b03 | |||
| c324f1783e | |||
| 9361243065 | |||
| b00061cea7 | |||
| 3a59611726 | |||
| b324159be9 | |||
| f584a5aaa2 | |||
| 2077cf9152 | |||
| af07365b49 | |||
| 780cd92b98 | |||
| f9c77dedfa | |||
| a33915d690 | |||
| c5c85defb2 | |||
| d9e27021e1 | |||
| e7806fd477 | |||
| 20c373118c | |||
| 7308aaa9b4 | |||
| f872951880 | |||
| 8bde5d2e51 | |||
| ce7ae6fa27 | |||
| 9f1f04f313 |
@@ -105,6 +105,7 @@ add_subdirectory(rc4)
|
||||
add_subdirectory(conf)
|
||||
add_subdirectory(chacha)
|
||||
add_subdirectory(poly1305)
|
||||
add_subdirectory(curve25519)
|
||||
|
||||
# Level 1, depends only on 0.*
|
||||
add_subdirectory(digest)
|
||||
@@ -174,6 +175,7 @@ add_library(
|
||||
$<TARGET_OBJECTS:conf>
|
||||
$<TARGET_OBJECTS:chacha>
|
||||
$<TARGET_OBJECTS:poly1305>
|
||||
$<TARGET_OBJECTS:curve25519>
|
||||
$<TARGET_OBJECTS:buf>
|
||||
$<TARGET_OBJECTS:bn>
|
||||
$<TARGET_OBJECTS:bio>
|
||||
|
||||
@@ -43,3 +43,14 @@ add_library(
|
||||
x_bignum.c
|
||||
x_long.c
|
||||
)
|
||||
|
||||
add_executable(
|
||||
asn1_test
|
||||
|
||||
asn1_test.cc
|
||||
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
target_link_libraries(asn1_test crypto)
|
||||
add_dependencies(all_tests asn1_test)
|
||||
|
||||
+3
-1
@@ -125,6 +125,8 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
|
||||
{
|
||||
ret=a->length;
|
||||
i=a->data[0];
|
||||
if (ret == 1 && i == 0)
|
||||
neg = 0;
|
||||
if (!neg && (i > 127)) {
|
||||
pad=1;
|
||||
pb=0;
|
||||
@@ -158,7 +160,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
|
||||
p += a->length - 1;
|
||||
i = a->length;
|
||||
/* Copy zeros to destination as long as source is zero */
|
||||
while(!*n) {
|
||||
while(!*n && i > 1) {
|
||||
*(p--) = 0;
|
||||
n--;
|
||||
i--;
|
||||
|
||||
@@ -161,6 +161,11 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
p++;
|
||||
if (--max == 0) goto err;
|
||||
}
|
||||
|
||||
/* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */
|
||||
if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL)
|
||||
goto err;
|
||||
|
||||
*ptag=tag;
|
||||
*pclass=xclass;
|
||||
if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
|
||||
|
||||
@@ -61,6 +61,8 @@
|
||||
#include <openssl/mem.h>
|
||||
|
||||
|
||||
#define ASN1_PARSE_MAXDEPTH 128
|
||||
|
||||
static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
|
||||
int indent);
|
||||
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
|
||||
@@ -125,6 +127,13 @@ static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offse
|
||||
#else
|
||||
dump_indent = 6; /* Because we know BIO_dump_indent() */
|
||||
#endif
|
||||
|
||||
if (depth > ASN1_PARSE_MAXDEPTH)
|
||||
{
|
||||
BIO_puts(bp, "BAD RECURSION DEPTH\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p= *pp;
|
||||
tot=p+length;
|
||||
op=p-1;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* 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. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "../test/scoped_types.h"
|
||||
|
||||
|
||||
// kTag258 is an ASN.1 structure with a universal tag with number 258.
|
||||
static const uint8_t kTag258[] = {
|
||||
0x1f, 0x82, 0x02, 0x01, 0x00,
|
||||
};
|
||||
|
||||
static_assert(V_ASN1_NEG_INTEGER == 258,
|
||||
"V_ASN1_NEG_INTEGER changed. Update kTag258 to collide with it.");
|
||||
|
||||
bool TestLargeTags() {
|
||||
const uint8_t *p = kTag258;
|
||||
ScopedASN1_TYPE obj(d2i_ASN1_TYPE(NULL, &p, sizeof(kTag258)));
|
||||
if (obj) {
|
||||
fprintf(stderr, "Parsed value with illegal tag (type = %d).\n", obj->type);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
CRYPTO_library_init();
|
||||
|
||||
if (!TestLargeTags()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -170,6 +170,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
|
||||
int otag;
|
||||
int ret = 0;
|
||||
ASN1_VALUE **pchptr, *ptmpval;
|
||||
int combine = aclass & ASN1_TFLG_COMBINE;
|
||||
if (!pval)
|
||||
return 0;
|
||||
if (aux && aux->asn1_cb)
|
||||
@@ -526,7 +527,8 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
|
||||
auxerr:
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
|
||||
err:
|
||||
ASN1_item_ex_free(pval, it);
|
||||
if (combine == 0)
|
||||
ASN1_item_ex_free(pval, it);
|
||||
if (errtt)
|
||||
ERR_add_error_data(4, "Field=", errtt->field_name,
|
||||
", Type=", it->sname);
|
||||
@@ -742,7 +744,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
|
||||
{
|
||||
/* Nothing special */
|
||||
ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
|
||||
-1, 0, opt, ctx);
|
||||
-1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx);
|
||||
if (!ret)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
/* ASN1_PCTX routines */
|
||||
|
||||
ASN1_PCTX default_pctx =
|
||||
static ASN1_PCTX default_pctx =
|
||||
{
|
||||
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
|
||||
0, /* nm_flags */
|
||||
|
||||
+4
-21
@@ -56,6 +56,8 @@
|
||||
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
@@ -311,27 +313,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
|
||||
}
|
||||
}
|
||||
|
||||
if (rp != ap) {
|
||||
for (;;) {
|
||||
if (!dif--) {
|
||||
break;
|
||||
}
|
||||
rp[0] = ap[0];
|
||||
if (!dif--) {
|
||||
break;
|
||||
}
|
||||
rp[1] = ap[1];
|
||||
if (!dif--) {
|
||||
break;
|
||||
}
|
||||
rp[2] = ap[2];
|
||||
if (!dif--) {
|
||||
break;
|
||||
}
|
||||
rp[3] = ap[3];
|
||||
rp += 4;
|
||||
ap += 4;
|
||||
}
|
||||
if (dif > 0 && rp != ap) {
|
||||
memcpy(rp, ap, sizeof(*rp) * dif);
|
||||
}
|
||||
|
||||
r->top = max;
|
||||
|
||||
@@ -1770,6 +1770,15 @@ sqr8x_reduction:
|
||||
.align 32
|
||||
.L8x_tail_done:
|
||||
add (%rdx),%r8 # can this overflow?
|
||||
adc \$0,%r9
|
||||
adc \$0,%r10
|
||||
adc \$0,%r11
|
||||
adc \$0,%r12
|
||||
adc \$0,%r13
|
||||
adc \$0,%r14
|
||||
adc \$0,%r15 # can't overflow, because we
|
||||
# started with "overhung" part
|
||||
# of multiplication
|
||||
xor %rax,%rax
|
||||
|
||||
neg $carry
|
||||
@@ -3116,6 +3125,15 @@ sqrx8x_reduction:
|
||||
.align 32
|
||||
.Lsqrx8x_tail_done:
|
||||
add 24+8(%rsp),%r8 # can this overflow?
|
||||
adc \$0,%r9
|
||||
adc \$0,%r10
|
||||
adc \$0,%r11
|
||||
adc \$0,%r12
|
||||
adc \$0,%r13
|
||||
adc \$0,%r14
|
||||
adc \$0,%r15 # can't overflow, because we
|
||||
# started with "overhung" part
|
||||
# of multiplication
|
||||
mov $carry,%rax # xor %rax,%rax
|
||||
|
||||
sub 16+8(%rsp),$carry # mov 16(%rsp),%cf
|
||||
@@ -3159,13 +3177,11 @@ my ($rptr,$nptr)=("%rdx","%rbp");
|
||||
my @ri=map("%r$_",(10..13));
|
||||
my @ni=map("%r$_",(14..15));
|
||||
$code.=<<___;
|
||||
xor %rbx,%rbx
|
||||
xor %ebx,%ebx
|
||||
sub %r15,%rsi # compare top-most words
|
||||
adc %rbx,%rbx
|
||||
mov %rcx,%r10 # -$num
|
||||
.byte 0x67
|
||||
or %rbx,%rax
|
||||
.byte 0x67
|
||||
mov %rcx,%r9 # -$num
|
||||
xor \$1,%rax
|
||||
sar \$3+2,%rcx # cf=0
|
||||
|
||||
+3
-4
@@ -166,11 +166,10 @@ void BN_clear(BIGNUM *bn) {
|
||||
}
|
||||
|
||||
const BIGNUM *BN_value_one(void) {
|
||||
static const BN_ULONG data_one = 1;
|
||||
static const BIGNUM const_one = {(BN_ULONG *)&data_one, 1, 1, 0,
|
||||
BN_FLG_STATIC_DATA};
|
||||
static const BN_ULONG kOneLimbs[1] = { 1 };
|
||||
static const BIGNUM kOne = STATIC_BIGNUM(kOneLimbs);
|
||||
|
||||
return &const_one;
|
||||
return &kOne;
|
||||
}
|
||||
|
||||
void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags) {
|
||||
|
||||
+28
-7
@@ -330,6 +330,13 @@ int main(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
|
||||
BIGNUM *raw = NULL;
|
||||
int ret = BN_hex2bn(&raw, in);
|
||||
out->reset(raw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_add(FILE *fp) {
|
||||
ScopedBIGNUM a(BN_new());
|
||||
ScopedBIGNUM b(BN_new());
|
||||
@@ -1107,6 +1114,27 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Regression test for carry propagation bug in sqr8x_reduction.
|
||||
if (!HexToBIGNUM(&a, "050505050505") ||
|
||||
!HexToBIGNUM(&b, "02") ||
|
||||
!HexToBIGNUM(
|
||||
&c,
|
||||
"4141414141414141414141274141414141414141414141414141414141414141"
|
||||
"4141414141414141414141414141414141414141414141414141414141414141"
|
||||
"4141414141414141414141800000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000001") ||
|
||||
!BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx) ||
|
||||
!BN_mul(e.get(), a.get(), a.get(), ctx)) {
|
||||
return false;
|
||||
}
|
||||
if (BN_cmp(d.get(), e.get()) != 0) {
|
||||
fprintf(stderr, "BN_mod_exp and BN_mul produce different results!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1545,13 +1573,6 @@ static bool test_dec2bn(BN_CTX *ctx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
|
||||
BIGNUM *raw = NULL;
|
||||
int ret = BN_hex2bn(&raw, in);
|
||||
out->reset(raw);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool test_hex2bn(BN_CTX *ctx) {
|
||||
ScopedBIGNUM bn;
|
||||
int ret = HexToBIGNUM(&bn, "0");
|
||||
|
||||
+6
-6
@@ -260,10 +260,10 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
q = BN_MASK2;
|
||||
} else {
|
||||
/* n0 < d0 */
|
||||
#ifdef BN_LLONG
|
||||
#ifdef BN_ULLONG
|
||||
BN_ULLONG t2;
|
||||
|
||||
#if defined(BN_LLONG) && !defined(div_asm)
|
||||
#if defined(BN_ULLONG) && !defined(div_asm)
|
||||
q = (BN_ULONG)(((((BN_ULLONG)n0) << BN_BITS2) | n1) / d0);
|
||||
#else
|
||||
q = div_asm(n0, n1, d0);
|
||||
@@ -288,7 +288,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
}
|
||||
t2 -= d1;
|
||||
}
|
||||
#else /* !BN_LLONG */
|
||||
#else /* !BN_ULLONG */
|
||||
BN_ULONG t2l, t2h;
|
||||
|
||||
#if defined(div_asm)
|
||||
@@ -331,7 +331,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
|
||||
}
|
||||
t2l -= d1;
|
||||
}
|
||||
#endif /* !BN_LLONG */
|
||||
#endif /* !BN_ULLONG */
|
||||
}
|
||||
|
||||
l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
|
||||
@@ -601,7 +601,7 @@ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) {
|
||||
}
|
||||
|
||||
BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
|
||||
#ifndef BN_LLONG
|
||||
#ifndef BN_ULLONG
|
||||
BN_ULONG ret = 0;
|
||||
#else
|
||||
BN_ULLONG ret = 0;
|
||||
@@ -614,7 +614,7 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
|
||||
|
||||
w &= BN_MASK2;
|
||||
for (i = a->top - 1; i >= 0; i--) {
|
||||
#ifndef BN_LLONG
|
||||
#ifndef BN_ULLONG
|
||||
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
|
||||
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
|
||||
#else
|
||||
|
||||
+1
-1
@@ -279,7 +279,7 @@ BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
|
||||
* sign*Y*a == A (mod |n|).
|
||||
*/
|
||||
|
||||
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) {
|
||||
if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS2 <= 32 ? 450 : 2048))) {
|
||||
/* Binary inversion algorithm; requires odd modulus.
|
||||
* This is faster than the general algorithm if the modulus
|
||||
* is sufficiently small (about 400 .. 500 bits on 32-bit
|
||||
|
||||
+13
-19
@@ -69,13 +69,7 @@
|
||||
(!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) || \
|
||||
(defined(OPENSSL_X86_64) && defined(OPENSSL_WINDOWS))
|
||||
|
||||
#if defined(OPENSSL_WINDOWS)
|
||||
#define alloca _alloca
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef BN_LLONG
|
||||
#ifdef BN_ULLONG
|
||||
#define mul_add(r, a, w, c) \
|
||||
{ \
|
||||
BN_ULLONG t; \
|
||||
@@ -222,9 +216,9 @@
|
||||
(c) = h & BN_MASK2; \
|
||||
(r) = l & BN_MASK2; \
|
||||
}
|
||||
#endif /* !BN_LLONG */
|
||||
#endif /* !BN_ULLONG */
|
||||
|
||||
#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
|
||||
#if defined(BN_ULLONG) || defined(BN_UMULT_HIGH)
|
||||
|
||||
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
|
||||
BN_ULONG w) {
|
||||
@@ -304,7 +298,7 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
|
||||
#else /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
|
||||
|
||||
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
|
||||
BN_ULONG w) {
|
||||
@@ -390,9 +384,9 @@ void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !(defined(BN_LLONG) || defined(BN_UMULT_HIGH)) */
|
||||
#endif /* !(defined(BN_ULLONG) || defined(BN_UMULT_HIGH)) */
|
||||
|
||||
#if defined(BN_LLONG)
|
||||
#if defined(BN_ULLONG)
|
||||
|
||||
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
|
||||
return (BN_ULONG)(((((BN_ULLONG)h) << BN_BITS2) | l) / (BN_ULLONG)d);
|
||||
@@ -470,9 +464,9 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* !defined(BN_LLONG) */
|
||||
#endif /* !defined(BN_ULLONG) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
#ifdef BN_ULLONG
|
||||
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
int n) {
|
||||
BN_ULLONG ll = 0;
|
||||
@@ -512,7 +506,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
return (BN_ULONG)ll;
|
||||
}
|
||||
|
||||
#else /* !BN_LLONG */
|
||||
#else /* !BN_ULLONG */
|
||||
|
||||
BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
int n) {
|
||||
@@ -569,7 +563,7 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
return (BN_ULONG)c;
|
||||
}
|
||||
|
||||
#endif /* !BN_LLONG */
|
||||
#endif /* !BN_ULLONG */
|
||||
|
||||
BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
int n) {
|
||||
@@ -631,7 +625,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
|
||||
/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
|
||||
|
||||
#ifdef BN_LLONG
|
||||
#ifdef BN_ULLONG
|
||||
|
||||
/* Keep in mind that additions to multiplication result can not overflow,
|
||||
* because its high half cannot be all-ones. */
|
||||
@@ -722,7 +716,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
|
||||
#else /* !BN_LLONG */
|
||||
#else /* !BN_ULLONG */
|
||||
|
||||
/* Keep in mind that additions to hi can not overflow, because
|
||||
* the high word of a multiplication result cannot be all-ones. */
|
||||
@@ -774,7 +768,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
|
||||
} while (0)
|
||||
|
||||
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
|
||||
#endif /* !BN_LLONG */
|
||||
#endif /* !BN_ULLONG */
|
||||
|
||||
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) {
|
||||
BN_ULONG c1, c2, c3;
|
||||
|
||||
+23
-20
@@ -144,44 +144,41 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
/* MSVC doesn't support two-word integers on 64-bit. */
|
||||
#define BN_LLONG __int128_t
|
||||
#define BN_ULLONG __uint128_t
|
||||
#endif
|
||||
|
||||
#define BN_BITS 128
|
||||
#define BN_BITS2 64
|
||||
#define BN_BYTES 8
|
||||
#define BN_BITS4 32
|
||||
#define BN_MASK (0xffffffffffffffffffffffffffffffffLL)
|
||||
#define BN_MASK2 (0xffffffffffffffffL)
|
||||
#define BN_MASK2l (0xffffffffL)
|
||||
#define BN_MASK2h (0xffffffff00000000L)
|
||||
#define BN_MASK2h1 (0xffffffff80000000L)
|
||||
#define BN_TBIT (0x8000000000000000L)
|
||||
#define BN_MASK2 (0xffffffffffffffffUL)
|
||||
#define BN_MASK2l (0xffffffffUL)
|
||||
#define BN_MASK2h (0xffffffff00000000UL)
|
||||
#define BN_MASK2h1 (0xffffffff80000000UL)
|
||||
#define BN_TBIT (0x8000000000000000UL)
|
||||
#define BN_DEC_CONV (10000000000000000000UL)
|
||||
#define BN_DEC_NUM 19
|
||||
#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
|
||||
|
||||
#elif defined(OPENSSL_32_BIT)
|
||||
|
||||
#define BN_LLONG int64_t
|
||||
#define BN_ULLONG uint64_t
|
||||
#define BN_MASK (0xffffffffffffffffLL)
|
||||
#define BN_BITS 64
|
||||
#define BN_BITS2 32
|
||||
#define BN_BYTES 4
|
||||
#define BN_BITS4 16
|
||||
#define BN_MASK2 (0xffffffffL)
|
||||
#define BN_MASK2l (0xffff)
|
||||
#define BN_MASK2h1 (0xffff8000L)
|
||||
#define BN_MASK2h (0xffff0000L)
|
||||
#define BN_TBIT (0x80000000L)
|
||||
#define BN_DEC_CONV (1000000000L)
|
||||
#define BN_MASK2 (0xffffffffUL)
|
||||
#define BN_MASK2l (0xffffUL)
|
||||
#define BN_MASK2h1 (0xffff8000UL)
|
||||
#define BN_MASK2h (0xffff0000UL)
|
||||
#define BN_TBIT (0x80000000UL)
|
||||
#define BN_DEC_CONV (1000000000UL)
|
||||
#define BN_DEC_NUM 9
|
||||
#define TOBN(hi, lo) lo, hi
|
||||
|
||||
#else
|
||||
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
|
||||
#endif
|
||||
|
||||
|
||||
/* Pentium pro 16,16,16,32,64 */
|
||||
/* Alpha 16,16,16,16.64 */
|
||||
#define BN_MULL_SIZE_NORMAL (16) /* 32 */
|
||||
@@ -190,7 +187,13 @@ BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
|
||||
#define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32) /* 32 */
|
||||
#define BN_MONT_CTX_SET_SIZE_WORD (64) /* 32 */
|
||||
|
||||
#if defined(BN_LLONG)
|
||||
#define STATIC_BIGNUM(x) \
|
||||
{ \
|
||||
(BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \
|
||||
sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
|
||||
}
|
||||
|
||||
#if defined(BN_ULLONG)
|
||||
#define Lw(t) (((BN_ULONG)(t))&BN_MASK2)
|
||||
#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
|
||||
#endif
|
||||
@@ -220,7 +223,7 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
|
||||
int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
const BN_ULONG *np, const BN_ULONG *n0, int num);
|
||||
|
||||
#if !defined(BN_LLONG)
|
||||
#if !defined(BN_ULLONG)
|
||||
|
||||
#define LBITS(a) ((a) & BN_MASK2l)
|
||||
#define HBITS(a) (((a) >> BN_BITS4) & BN_MASK2l)
|
||||
@@ -252,7 +255,7 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
(h) = ht; \
|
||||
}
|
||||
|
||||
#endif /* !defined(BN_LLONG) */
|
||||
#endif /* !defined(BN_ULLONG) */
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
|
||||
# if defined(__GNUC__) && __GNUC__ >= 2
|
||||
|
||||
@@ -134,7 +134,6 @@ BN_MONT_CTX *BN_MONT_CTX_new(void) {
|
||||
memset(ret, 0, sizeof(BN_MONT_CTX));
|
||||
BN_init(&ret->RR);
|
||||
BN_init(&ret->N);
|
||||
BN_init(&ret->Ni);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -146,7 +145,6 @@ void BN_MONT_CTX_free(BN_MONT_CTX *mont) {
|
||||
|
||||
BN_free(&mont->RR);
|
||||
BN_free(&mont->N);
|
||||
BN_free(&mont->Ni);
|
||||
OPENSSL_free(mont);
|
||||
}
|
||||
|
||||
@@ -156,11 +154,9 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) {
|
||||
}
|
||||
|
||||
if (!BN_copy(&to->RR, &from->RR) ||
|
||||
!BN_copy(&to->N, &from->N) ||
|
||||
!BN_copy(&to->Ni, &from->Ni)) {
|
||||
!BN_copy(&to->N, &from->N)) {
|
||||
return NULL;
|
||||
}
|
||||
to->ri = from->ri;
|
||||
to->n0[0] = from->n0[0];
|
||||
to->n0[1] = from->n0[1];
|
||||
return to;
|
||||
@@ -193,8 +189,6 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
|
||||
tmod.dmax = 2;
|
||||
tmod.neg = 0;
|
||||
|
||||
mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
|
||||
|
||||
#if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2 <= 32)
|
||||
/* Only certain BN_BITS2<=32 platforms actually make use of
|
||||
* n0[1], and we could use the #else case (with a shorter R
|
||||
@@ -278,9 +272,10 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
|
||||
mont->n0[1] = 0;
|
||||
#endif
|
||||
|
||||
/* setup RR for conversions */
|
||||
/* RR = (2^ri)^2 == 2^(ri*2) == 1 << (ri*2), which has its (ri*2)th bit set. */
|
||||
int ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
|
||||
BN_zero(&(mont->RR));
|
||||
if (!BN_set_bit(&(mont->RR), mont->ri * 2)) {
|
||||
if (!BN_set_bit(&(mont->RR), ri * 2)) {
|
||||
goto err;
|
||||
}
|
||||
if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) {
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#if !defined(__STDC_CONSTANT_MACROS)
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -22,7 +26,6 @@
|
||||
#include <openssl/bytestring.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
#include "../test/scoped_types.h"
|
||||
|
||||
|
||||
@@ -341,12 +344,14 @@ static bool TestCBBPrefixed() {
|
||||
size_t buf_len;
|
||||
CBB cbb, contents, inner_contents, inner_inner_contents;
|
||||
|
||||
if (!CBB_init(&cbb, 0)) {
|
||||
return false;
|
||||
}
|
||||
if (!CBB_add_u8_length_prefixed(&cbb, &contents) ||
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
CBB_len(&cbb) != 0 ||
|
||||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
|
||||
!CBB_add_u8_length_prefixed(&cbb, &contents) ||
|
||||
!CBB_add_u8(&contents, 1) ||
|
||||
CBB_len(&contents) != 1 ||
|
||||
!CBB_flush(&cbb) ||
|
||||
CBB_len(&cbb) != 3 ||
|
||||
!CBB_add_u16_length_prefixed(&cbb, &contents) ||
|
||||
!CBB_add_u16(&contents, 0x203) ||
|
||||
!CBB_add_u24_length_prefixed(&cbb, &contents) ||
|
||||
@@ -627,9 +632,9 @@ static const ASN1Uint64Test kASN1Uint64Tests[] = {
|
||||
{127, "\x02\x01\x7f", 3},
|
||||
{128, "\x02\x02\x00\x80", 4},
|
||||
{0xdeadbeef, "\x02\x05\x00\xde\xad\xbe\xef", 7},
|
||||
{OPENSSL_U64(0x0102030405060708),
|
||||
{UINT64_C(0x0102030405060708),
|
||||
"\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
|
||||
{OPENSSL_U64(0xffffffffffffffff),
|
||||
{UINT64_C(0xffffffffffffffff),
|
||||
"\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
|
||||
};
|
||||
|
||||
|
||||
+26
-26
@@ -25,6 +25,7 @@ void CBB_zero(CBB *cbb) {
|
||||
}
|
||||
|
||||
static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
|
||||
/* This assumes that |cbb| has already been zeroed. */
|
||||
struct cbb_buffer_st *base;
|
||||
|
||||
base = OPENSSL_malloc(sizeof(struct cbb_buffer_st));
|
||||
@@ -37,16 +38,15 @@ static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
|
||||
base->cap = cap;
|
||||
base->can_resize = 1;
|
||||
|
||||
memset(cbb, 0, sizeof(CBB));
|
||||
cbb->base = base;
|
||||
cbb->is_top_level = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CBB_init(CBB *cbb, size_t initial_capacity) {
|
||||
uint8_t *buf;
|
||||
CBB_zero(cbb);
|
||||
|
||||
buf = OPENSSL_malloc(initial_capacity);
|
||||
uint8_t *buf = OPENSSL_malloc(initial_capacity);
|
||||
if (initial_capacity > 0 && buf == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@@ -60,6 +60,8 @@ int CBB_init(CBB *cbb, size_t initial_capacity) {
|
||||
}
|
||||
|
||||
int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) {
|
||||
CBB_zero(cbb);
|
||||
|
||||
if (!cbb_init(cbb, buf, len)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -177,28 +179,28 @@ int CBB_flush(CBB *cbb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cbb->child == NULL || cbb->pending_len_len == 0) {
|
||||
if (cbb->child == NULL || cbb->child->pending_len_len == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
child_start = cbb->offset + cbb->pending_len_len;
|
||||
child_start = cbb->child->offset + cbb->child->pending_len_len;
|
||||
|
||||
if (!CBB_flush(cbb->child) ||
|
||||
child_start < cbb->offset ||
|
||||
child_start < cbb->child->offset ||
|
||||
cbb->base->len < child_start) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = cbb->base->len - child_start;
|
||||
|
||||
if (cbb->pending_is_asn1) {
|
||||
if (cbb->child->pending_is_asn1) {
|
||||
/* For ASN.1 we assume that we'll only need a single byte for the length.
|
||||
* If that turned out to be incorrect, we have to move the contents along
|
||||
* in order to make space. */
|
||||
size_t len_len;
|
||||
uint8_t initial_length_byte;
|
||||
|
||||
assert (cbb->pending_len_len == 1);
|
||||
assert (cbb->child->pending_len_len == 1);
|
||||
|
||||
if (len > 0xfffffffe) {
|
||||
/* Too large. */
|
||||
@@ -230,12 +232,13 @@ int CBB_flush(CBB *cbb) {
|
||||
memmove(cbb->base->buf + child_start + extra_bytes,
|
||||
cbb->base->buf + child_start, len);
|
||||
}
|
||||
cbb->base->buf[cbb->offset++] = initial_length_byte;
|
||||
cbb->pending_len_len = len_len - 1;
|
||||
cbb->base->buf[cbb->child->offset++] = initial_length_byte;
|
||||
cbb->child->pending_len_len = len_len - 1;
|
||||
}
|
||||
|
||||
for (i = cbb->pending_len_len - 1; i < cbb->pending_len_len; i--) {
|
||||
cbb->base->buf[cbb->offset + i] = len;
|
||||
for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len;
|
||||
i--) {
|
||||
cbb->base->buf[cbb->child->offset + i] = len;
|
||||
len >>= 8;
|
||||
}
|
||||
if (len != 0) {
|
||||
@@ -244,17 +247,15 @@ int CBB_flush(CBB *cbb) {
|
||||
|
||||
cbb->child->base = NULL;
|
||||
cbb->child = NULL;
|
||||
cbb->pending_len_len = 0;
|
||||
cbb->pending_is_asn1 = 0;
|
||||
cbb->offset = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t CBB_len(const CBB *cbb) {
|
||||
assert(cbb->child == NULL);
|
||||
assert(cbb->offset + cbb->pending_len_len <= cbb->base->len);
|
||||
|
||||
return cbb->base->len;
|
||||
return cbb->base->len - cbb->offset - cbb->pending_len_len;
|
||||
}
|
||||
|
||||
static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
|
||||
@@ -265,7 +266,7 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
|
||||
return 0;
|
||||
}
|
||||
|
||||
cbb->offset = cbb->base->len;
|
||||
size_t offset = cbb->base->len;
|
||||
if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -274,8 +275,9 @@ static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
|
||||
memset(out_contents, 0, sizeof(CBB));
|
||||
out_contents->base = cbb->base;
|
||||
cbb->child = out_contents;
|
||||
cbb->pending_len_len = len_len;
|
||||
cbb->pending_is_asn1 = 0;
|
||||
cbb->child->offset = offset;
|
||||
cbb->child->pending_len_len = len_len;
|
||||
cbb->child->pending_is_asn1 = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -303,7 +305,7 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cbb->offset = cbb->base->len;
|
||||
size_t offset = cbb->base->len;
|
||||
if (!CBB_add_u8(cbb, 0)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -311,8 +313,9 @@ int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag) {
|
||||
memset(out_contents, 0, sizeof(CBB));
|
||||
out_contents->base = cbb->base;
|
||||
cbb->child = out_contents;
|
||||
cbb->pending_len_len = 1;
|
||||
cbb->pending_is_asn1 = 1;
|
||||
cbb->child->offset = offset;
|
||||
cbb->child->pending_len_len = 1;
|
||||
cbb->child->pending_is_asn1 = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -365,13 +368,10 @@ void CBB_discard_child(CBB *cbb) {
|
||||
return;
|
||||
}
|
||||
|
||||
cbb->base->len = cbb->offset;
|
||||
cbb->base->len = cbb->child->offset;
|
||||
|
||||
cbb->child->base = NULL;
|
||||
cbb->child = NULL;
|
||||
cbb->pending_len_len = 0;
|
||||
cbb->pending_is_asn1 = 0;
|
||||
cbb->offset = 0;
|
||||
}
|
||||
|
||||
int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) {
|
||||
|
||||
@@ -200,7 +200,7 @@ struct AEADName {
|
||||
static const struct AEADName kAEADs[] = {
|
||||
{ "aes-128-gcm", EVP_aead_aes_128_gcm },
|
||||
{ "aes-256-gcm", EVP_aead_aes_256_gcm },
|
||||
{ "chacha20-poly1305", EVP_aead_chacha20_poly1305_rfc7539 },
|
||||
{ "chacha20-poly1305", EVP_aead_chacha20_poly1305 },
|
||||
{ "chacha20-poly1305-old", EVP_aead_chacha20_poly1305_old },
|
||||
{ "rc4-md5-tls", EVP_aead_rc4_md5_tls },
|
||||
{ "rc4-sha1-tls", EVP_aead_rc4_sha1_tls },
|
||||
|
||||
@@ -1652,7 +1652,7 @@ static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
|
||||
if (in_len + aes_ctx->tag_len < in_len ||
|
||||
/* This input is so large it would overflow the 32-bit block counter. */
|
||||
in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
|
||||
in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -108,10 +108,11 @@ static void aead_poly1305(aead_poly1305_update update,
|
||||
CRYPTO_poly1305_finish(&ctx, tag);
|
||||
}
|
||||
|
||||
static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
|
||||
uint8_t *out, size_t *out_len, size_t max_out_len,
|
||||
const uint8_t nonce[12], const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
static int seal_impl(aead_poly1305_update poly1305_update,
|
||||
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
|
||||
size_t max_out_len, const uint8_t nonce[12],
|
||||
const uint8_t *in, size_t in_len, const uint8_t *ad,
|
||||
size_t ad_len) {
|
||||
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
|
||||
const uint64_t in_len_64 = in_len;
|
||||
|
||||
@@ -146,10 +147,11 @@ static int seal(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int open(aead_poly1305_update poly1305_update, const EVP_AEAD_CTX *ctx,
|
||||
uint8_t *out, size_t *out_len, size_t max_out_len,
|
||||
const uint8_t nonce[12], const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
static int open_impl(aead_poly1305_update poly1305_update,
|
||||
const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
|
||||
size_t max_out_len, const uint8_t nonce[12],
|
||||
const uint8_t *in, size_t in_len, const uint8_t *ad,
|
||||
size_t ad_len) {
|
||||
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
|
||||
size_t plaintext_len;
|
||||
const uint64_t in_len_64 = in_len;
|
||||
@@ -212,8 +214,8 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
return seal(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
|
||||
in_len, ad, ad_len);
|
||||
return seal_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
|
||||
in_len, ad, ad_len);
|
||||
}
|
||||
|
||||
static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
@@ -225,8 +227,8 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
return open(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
|
||||
in_len, ad, ad_len);
|
||||
return open_impl(poly1305_update, ctx, out, out_len, max_out_len, nonce, in,
|
||||
in_len, ad, ad_len);
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_chacha20_poly1305 = {
|
||||
@@ -243,10 +245,14 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
|
||||
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
|
||||
return &aead_chacha20_poly1305;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
|
||||
return EVP_aead_chacha20_poly1305();
|
||||
}
|
||||
|
||||
static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
|
||||
size_t ad_len, const uint8_t *ciphertext,
|
||||
size_t ciphertext_len) {
|
||||
@@ -267,8 +273,8 @@ static int aead_chacha20_poly1305_old_seal(
|
||||
uint8_t nonce_96[12];
|
||||
memset(nonce_96, 0, 4);
|
||||
memcpy(nonce_96 + 4, nonce, 8);
|
||||
return seal(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
|
||||
in_len, ad, ad_len);
|
||||
return seal_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
|
||||
nonce_96, in, in_len, ad, ad_len);
|
||||
}
|
||||
|
||||
static int aead_chacha20_poly1305_old_open(
|
||||
@@ -282,8 +288,8 @@ static int aead_chacha20_poly1305_old_open(
|
||||
uint8_t nonce_96[12];
|
||||
memset(nonce_96, 0, 4);
|
||||
memcpy(nonce_96 + 4, nonce, 8);
|
||||
return open(poly1305_update_old, ctx, out, out_len, max_out_len, nonce_96, in,
|
||||
in_len, ad, ad_len);
|
||||
return open_impl(poly1305_update_old, ctx, out, out_len, max_out_len,
|
||||
nonce_96, in, in_len, ad, ad_len);
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_chacha20_poly1305_old = {
|
||||
@@ -303,7 +309,3 @@ static const EVP_AEAD aead_chacha20_poly1305_old = {
|
||||
const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void) {
|
||||
return &aead_chacha20_poly1305_old;
|
||||
}
|
||||
|
||||
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
|
||||
return &aead_chacha20_poly1305_old;
|
||||
}
|
||||
|
||||
@@ -54,21 +54,13 @@
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#include <openssl/aead.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/cpu.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/obj.h>
|
||||
#include <openssl/rc4.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
|
||||
const uint8_t *iv, int enc) {
|
||||
@@ -93,306 +85,3 @@ static const EVP_CIPHER rc4 = {
|
||||
NULL /* cleanup */, NULL /* ctrl */, };
|
||||
|
||||
const EVP_CIPHER *EVP_rc4(void) { return &rc4; }
|
||||
|
||||
|
||||
struct aead_rc4_md5_tls_ctx {
|
||||
RC4_KEY rc4;
|
||||
MD5_CTX head, tail, md;
|
||||
size_t payload_length;
|
||||
unsigned char tag_len;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
|
||||
size_t tag_len) {
|
||||
struct aead_rc4_md5_tls_ctx *rc4_ctx;
|
||||
size_t i;
|
||||
uint8_t hmac_key[MD5_CBLOCK];
|
||||
|
||||
if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
|
||||
tag_len = MD5_DIGEST_LENGTH;
|
||||
}
|
||||
|
||||
if (tag_len > MD5_DIGEST_LENGTH) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The keys consists of |MD5_DIGEST_LENGTH| bytes of HMAC(MD5) key followed
|
||||
* by some number of bytes of RC4 key. */
|
||||
if (key_len <= MD5_DIGEST_LENGTH) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc4_ctx = OPENSSL_malloc(sizeof(struct aead_rc4_md5_tls_ctx));
|
||||
if (rc4_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
memset(rc4_ctx, 0, sizeof(struct aead_rc4_md5_tls_ctx));
|
||||
|
||||
RC4_set_key(&rc4_ctx->rc4, key_len - MD5_DIGEST_LENGTH,
|
||||
key + MD5_DIGEST_LENGTH);
|
||||
|
||||
memset(hmac_key, 0, sizeof(hmac_key));
|
||||
memcpy(hmac_key, key, MD5_DIGEST_LENGTH);
|
||||
for (i = 0; i < sizeof(hmac_key); i++) {
|
||||
hmac_key[i] ^= 0x36;
|
||||
}
|
||||
MD5_Init(&rc4_ctx->head);
|
||||
MD5_Update(&rc4_ctx->head, hmac_key, sizeof(hmac_key));
|
||||
for (i = 0; i < sizeof(hmac_key); i++) {
|
||||
hmac_key[i] ^= 0x36 ^ 0x5c;
|
||||
}
|
||||
MD5_Init(&rc4_ctx->tail);
|
||||
MD5_Update(&rc4_ctx->tail, hmac_key, sizeof(hmac_key));
|
||||
|
||||
rc4_ctx->tag_len = tag_len;
|
||||
ctx->aead_state = rc4_ctx;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void aead_rc4_md5_tls_cleanup(EVP_AEAD_CTX *ctx) {
|
||||
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
|
||||
OPENSSL_cleanse(rc4_ctx, sizeof(struct aead_rc4_md5_tls_ctx));
|
||||
OPENSSL_free(rc4_ctx);
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
|
||||
#define STITCHED_CALL
|
||||
|
||||
/* rc4_md5_enc is defined in rc4_md5-x86_64.pl */
|
||||
void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, MD5_CTX *ctx,
|
||||
const void *inp, size_t blocks);
|
||||
#endif
|
||||
|
||||
static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
|
||||
MD5_CTX md;
|
||||
#if defined(STITCHED_CALL)
|
||||
size_t rc4_off, md5_off, blocks;
|
||||
#else
|
||||
const size_t rc4_off = 0;
|
||||
const size_t md5_off = 0;
|
||||
#endif
|
||||
uint8_t digest[MD5_DIGEST_LENGTH];
|
||||
|
||||
if (in_len + rc4_ctx->tag_len < in_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len + rc4_ctx->tag_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nonce_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX));
|
||||
/* The MAC's payload begins with the additional data. See
|
||||
* https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
|
||||
MD5_Update(&md, ad, ad_len);
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_extra[2];
|
||||
ad_extra[0] = (uint8_t)(in_len >> 8);
|
||||
ad_extra[1] = (uint8_t)(in_len & 0xff);
|
||||
MD5_Update(&md, ad_extra, sizeof(ad_extra));
|
||||
|
||||
#if defined(STITCHED_CALL)
|
||||
/* 32 is $MOD from rc4_md5-x86_64.pl. */
|
||||
rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
|
||||
md5_off = MD5_CBLOCK - md.num;
|
||||
/* Ensure RC4 is behind MD5. */
|
||||
if (rc4_off > md5_off) {
|
||||
md5_off += MD5_CBLOCK;
|
||||
}
|
||||
assert(md5_off >= rc4_off);
|
||||
|
||||
if (in_len > md5_off && (blocks = (in_len - md5_off) / MD5_CBLOCK) &&
|
||||
(OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
|
||||
/* Process the initial portions of the plaintext normally. */
|
||||
MD5_Update(&md, in, md5_off);
|
||||
RC4(&rc4_ctx->rc4, rc4_off, in, out);
|
||||
|
||||
/* Process the next |blocks| blocks of plaintext with stitched routines. */
|
||||
rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, in + md5_off,
|
||||
blocks);
|
||||
blocks *= MD5_CBLOCK;
|
||||
rc4_off += blocks;
|
||||
md5_off += blocks;
|
||||
md.Nh += blocks >> 29;
|
||||
md.Nl += blocks <<= 3;
|
||||
if (md.Nl < (unsigned int)blocks) {
|
||||
md.Nh++;
|
||||
}
|
||||
} else {
|
||||
rc4_off = 0;
|
||||
md5_off = 0;
|
||||
}
|
||||
#endif
|
||||
/* Finish computing the MAC. */
|
||||
MD5_Update(&md, in + md5_off, in_len - md5_off);
|
||||
MD5_Final(digest, &md);
|
||||
|
||||
memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX));
|
||||
MD5_Update(&md, digest, sizeof(digest));
|
||||
if (rc4_ctx->tag_len == MD5_DIGEST_LENGTH) {
|
||||
MD5_Final(out + in_len, &md);
|
||||
} else {
|
||||
MD5_Final(digest, &md);
|
||||
memcpy(out + in_len, digest, rc4_ctx->tag_len);
|
||||
}
|
||||
|
||||
/* Encrypt the remainder of the plaintext and the MAC. */
|
||||
RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off);
|
||||
RC4(&rc4_ctx->rc4, MD5_DIGEST_LENGTH, out + in_len, out + in_len);
|
||||
|
||||
*out_len = in_len + rc4_ctx->tag_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
size_t *out_len, size_t max_out_len,
|
||||
const uint8_t *nonce, size_t nonce_len,
|
||||
const uint8_t *in, size_t in_len,
|
||||
const uint8_t *ad, size_t ad_len) {
|
||||
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
|
||||
MD5_CTX md;
|
||||
size_t plaintext_len;
|
||||
#if defined(STITCHED_CALL)
|
||||
unsigned int l;
|
||||
size_t rc4_off, md5_off, blocks;
|
||||
extern unsigned int OPENSSL_ia32cap_P[];
|
||||
#else
|
||||
const size_t rc4_off = 0;
|
||||
const size_t md5_off = 0;
|
||||
#endif
|
||||
uint8_t digest[MD5_DIGEST_LENGTH];
|
||||
|
||||
if (in_len < rc4_ctx->tag_len) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
plaintext_len = in_len - rc4_ctx->tag_len;
|
||||
|
||||
if (nonce_len != 0) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (max_out_len < in_len) {
|
||||
/* This requires that the caller provide space for the MAC, even though it
|
||||
* will always be removed on return. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&md, &rc4_ctx->head, sizeof(MD5_CTX));
|
||||
/* The MAC's payload begins with the additional data. See
|
||||
* https://tools.ietf.org/html/rfc5246#section-6.2.3.1 */
|
||||
MD5_Update(&md, ad, ad_len);
|
||||
|
||||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the
|
||||
* length for legacy ciphers. */
|
||||
uint8_t ad_extra[2];
|
||||
ad_extra[0] = (uint8_t)(plaintext_len >> 8);
|
||||
ad_extra[1] = (uint8_t)(plaintext_len & 0xff);
|
||||
MD5_Update(&md, ad_extra, sizeof(ad_extra));
|
||||
|
||||
#if defined(STITCHED_CALL)
|
||||
rc4_off = 32 - 1 - (rc4_ctx->rc4.x & (32 - 1));
|
||||
md5_off = MD5_CBLOCK - md.num;
|
||||
/* Ensure MD5 is a full block behind RC4 so it has plaintext to operate on in
|
||||
* both normal and stitched routines. */
|
||||
if (md5_off > rc4_off) {
|
||||
rc4_off += 2 * MD5_CBLOCK;
|
||||
} else {
|
||||
rc4_off += MD5_CBLOCK;
|
||||
}
|
||||
|
||||
if (in_len > rc4_off && (blocks = (in_len - rc4_off) / MD5_CBLOCK) &&
|
||||
(OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
|
||||
/* Decrypt the initial portion of the ciphertext and digest the plaintext
|
||||
* normally. */
|
||||
RC4(&rc4_ctx->rc4, rc4_off, in, out);
|
||||
MD5_Update(&md, out, md5_off);
|
||||
|
||||
/* Decrypt and digest the next |blocks| blocks of ciphertext with the
|
||||
* stitched routines. */
|
||||
rc4_md5_enc(&rc4_ctx->rc4, in + rc4_off, out + rc4_off, &md, out + md5_off,
|
||||
blocks);
|
||||
blocks *= MD5_CBLOCK;
|
||||
rc4_off += blocks;
|
||||
md5_off += blocks;
|
||||
l = (md.Nl + (blocks << 3)) & 0xffffffffU;
|
||||
if (l < md.Nl) {
|
||||
md.Nh++;
|
||||
}
|
||||
md.Nl = l;
|
||||
md.Nh += blocks >> 29;
|
||||
} else {
|
||||
md5_off = 0;
|
||||
rc4_off = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Process the remainder of the input. */
|
||||
RC4(&rc4_ctx->rc4, in_len - rc4_off, in + rc4_off, out + rc4_off);
|
||||
MD5_Update(&md, out + md5_off, plaintext_len - md5_off);
|
||||
MD5_Final(digest, &md);
|
||||
|
||||
/* Calculate HMAC and verify it */
|
||||
memcpy(&md, &rc4_ctx->tail, sizeof(MD5_CTX));
|
||||
MD5_Update(&md, digest, MD5_DIGEST_LENGTH);
|
||||
MD5_Final(digest, &md);
|
||||
|
||||
if (CRYPTO_memcmp(out + plaintext_len, digest, rc4_ctx->tag_len)) {
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_len = plaintext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_rc4_md5_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
|
||||
const RC4_KEY **out_key) {
|
||||
struct aead_rc4_md5_tls_ctx *rc4_ctx = ctx->aead_state;
|
||||
*out_key = &rc4_ctx->rc4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_rc4_md5_tls = {
|
||||
16 + MD5_DIGEST_LENGTH, /* key len (RC4 + MD5) */
|
||||
0, /* nonce len */
|
||||
MD5_DIGEST_LENGTH, /* overhead */
|
||||
MD5_DIGEST_LENGTH, /* max tag length */
|
||||
aead_rc4_md5_tls_init,
|
||||
NULL, /* init_with_direction */
|
||||
aead_rc4_md5_tls_cleanup,
|
||||
aead_rc4_md5_tls_seal,
|
||||
aead_rc4_md5_tls_open,
|
||||
aead_rc4_md5_tls_get_rc4_state,
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
|
||||
|
||||
+38
-24
@@ -20,6 +20,7 @@
|
||||
#include <openssl/cipher.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/type_check.h>
|
||||
@@ -111,7 +112,6 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
|
||||
@@ -146,17 +146,13 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
* in-place. */
|
||||
uint8_t mac[EVP_MAX_MD_SIZE];
|
||||
unsigned mac_len;
|
||||
HMAC_CTX hmac_ctx;
|
||||
HMAC_CTX_init(&hmac_ctx);
|
||||
if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
|
||||
!HMAC_Update(&hmac_ctx, ad, ad_len) ||
|
||||
!HMAC_Update(&hmac_ctx, ad_extra, sizeof(ad_extra)) ||
|
||||
!HMAC_Update(&hmac_ctx, in, in_len) ||
|
||||
!HMAC_Final(&hmac_ctx, mac, &mac_len)) {
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
|
||||
!HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) ||
|
||||
!HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) ||
|
||||
!HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) ||
|
||||
!HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) {
|
||||
return 0;
|
||||
}
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
|
||||
/* Configure the explicit IV. */
|
||||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
|
||||
@@ -216,7 +212,6 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
|
||||
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
|
||||
@@ -324,18 +319,14 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
* implemented. */
|
||||
assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
|
||||
|
||||
HMAC_CTX hmac_ctx;
|
||||
HMAC_CTX_init(&hmac_ctx);
|
||||
unsigned mac_len_u;
|
||||
if (!HMAC_CTX_copy_ex(&hmac_ctx, &tls_ctx->hmac_ctx) ||
|
||||
!HMAC_Update(&hmac_ctx, ad_fixed, ad_len) ||
|
||||
!HMAC_Update(&hmac_ctx, out, data_len) ||
|
||||
!HMAC_Final(&hmac_ctx, mac, &mac_len_u)) {
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
|
||||
!HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) ||
|
||||
!HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) ||
|
||||
!HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) {
|
||||
return 0;
|
||||
}
|
||||
mac_len = mac_len_u;
|
||||
HMAC_CTX_cleanup(&hmac_ctx);
|
||||
|
||||
assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
|
||||
record_mac = &out[data_len];
|
||||
@@ -359,6 +350,13 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len,
|
||||
enum evp_aead_direction_t dir) {
|
||||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_md5(),
|
||||
0);
|
||||
}
|
||||
|
||||
static int aead_rc4_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
size_t key_len, size_t tag_len,
|
||||
enum evp_aead_direction_t dir) {
|
||||
@@ -433,8 +431,8 @@ static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init(
|
||||
EVP_sha1(), 1);
|
||||
}
|
||||
|
||||
static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
|
||||
const RC4_KEY **out_key) {
|
||||
static int aead_rc4_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
|
||||
const RC4_KEY **out_key) {
|
||||
const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state;
|
||||
if (EVP_CIPHER_CTX_cipher(&tls_ctx->cipher_ctx) != EVP_rc4()) {
|
||||
return 0;
|
||||
@@ -464,18 +462,32 @@ static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
|
||||
EVP_sha1(), 1 /* implicit iv */);
|
||||
}
|
||||
|
||||
static const EVP_AEAD aead_rc4_md5_tls = {
|
||||
MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
|
||||
0, /* nonce len */
|
||||
MD5_DIGEST_LENGTH, /* overhead */
|
||||
MD5_DIGEST_LENGTH, /* max tag length */
|
||||
NULL, /* init */
|
||||
aead_rc4_md5_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
aead_rc4_tls_get_rc4_state, /* get_rc4_state */
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_rc4_sha1_tls = {
|
||||
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
|
||||
0, /* nonce len */
|
||||
SHA_DIGEST_LENGTH, /* overhead */
|
||||
SHA_DIGEST_LENGTH, /* max tag length */
|
||||
NULL, /* init */
|
||||
NULL, /* init */
|
||||
aead_rc4_sha1_tls_init,
|
||||
aead_tls_cleanup,
|
||||
aead_tls_seal,
|
||||
aead_tls_open,
|
||||
aead_rc4_sha1_tls_get_rc4_state, /* get_rc4_state */
|
||||
NULL, /* get_iv */
|
||||
aead_rc4_tls_get_rc4_state, /* get_rc4_state */
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
|
||||
@@ -618,6 +630,8 @@ static const EVP_AEAD aead_null_sha1_tls = {
|
||||
NULL, /* get_iv */
|
||||
};
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
|
||||
|
||||
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
|
||||
|
||||
@@ -418,5 +418,107 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813
|
||||
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
|
||||
TAG: f7d3b58a34a86e99267e5db206f17bbe
|
||||
|
||||
# BoringSSL has additional tests here for truncated tags. *ring* doesn't
|
||||
# support tag truncation, so those tests were removed.
|
||||
KEY: 3304e4917ad7777b86c26a636292c9cc4c10d32003c49e07209eb0ef8505031a
|
||||
NONCE: 4d572d116fbd8c4d
|
||||
IN: 2f242c2ba33790ecef862b0e077ff8b15eb9d10cf2ff621ed65902494431dcbd
|
||||
AD: e699bbf250cdd93d229d0740e433897e2d19132e2b722df8b69bb6a7c2cf3b93
|
||||
CT: fb81e30436e437c7f686f86b1b65c73549a9d09db810d320785c3634934150b3
|
||||
TAG: 8b
|
||||
|
||||
KEY: ed6057bb163f1609ff28b938122f495e3d5ae4ec3dbd7456c9b5c82e28e952dc
|
||||
NONCE: e6ff6852f3a3afde
|
||||
IN: 3c50edc967eb0b3b2355f6400e0a036e796c8b7d72c5e583a86e820d53e76c43
|
||||
AD: 2441db55148e14e9e241d68296eb60d529408f0534143089671bce546db96d88
|
||||
CT: 6ecabccee31519374d4bed11296e7483d1cb759bea3f4446a96bda8b4ca6d7ac
|
||||
TAG: 355f
|
||||
|
||||
KEY: 73568183c1f9725af30e0f2067606ce802c3fe3ab5cff8d02b3db8c35176ee0d
|
||||
NONCE: 0bc9e19321b3d00a
|
||||
IN: ec2590af5ccd226a32ff750c1b029c11e3dd76c469a5579da9418e4c3fdc0d41
|
||||
AD: df30160ae0cbf2cf8992221bd62dffe691dd602afa784ca691479e957af3acf1
|
||||
CT: 9e8d8ac30626f8b831448d6976933aa5bb8c6dbc794e1f4b7eeb0e4a59342c07
|
||||
TAG: 9fd36a
|
||||
|
||||
KEY: 273bcb3f8c067da4ec3418799ad40e7e4aee74ad7e629499d646df4a7e585025
|
||||
NONCE: f60be3eb894b4030
|
||||
IN: 697498ba964d5ef401da4d94844fab1efc635e7157d0831a325bb5a4cf1fbd34
|
||||
AD: 9129715deab14f02c76ba8172571b1fa9d50365cd795bfccdfc28e7e7b4f66fc
|
||||
CT: bd4cd5af83be1c13933302675d9fcaf1c4cacdf269f6ff441d1ea2211c54e7ed
|
||||
TAG: 7ab12a37
|
||||
|
||||
KEY: ad39610c2e6a6d0961207390e076e972c2edadca885c92965fa648b2ce34fdbf
|
||||
NONCE: a90db690bba83b78
|
||||
IN: 31c49e3cd3d80a82e6b90316dfb94b38b8a23042519bf40c8181fec873c99002
|
||||
AD: ddbd7d821d18d44c66295abf245b227b5cf4366811b7b34c07679600abdbfc29
|
||||
CT: 94628fc303a0546edd51e966f2bd87968f37800c607d5e5a91f727fc1fec406f
|
||||
TAG: c22ec4e4c8
|
||||
|
||||
KEY: 29984954060ba06ece1bcfc0e50195f4632c6df48da1e02ae6c14f7065668971
|
||||
NONCE: cce53a25aeeaf747
|
||||
IN: b9b87433a9894f3c9ca8212623d62369a565a2edcddd276e07d611eda3597426
|
||||
AD: 19fa9aa59697559d8b46d9cd49c3b763c0b73b26b9e334a3eeac2c86fdbaca8d
|
||||
CT: b68c83397770c36f073710882fa86d43b0e54e8efef0ff75075604d0d7ec4e1b
|
||||
TAG: 40d4ab752f3d
|
||||
|
||||
KEY: 5c3b838b84100b2a818c0842e9fe19a7c50cf5f3ea73364c816ef588e500ff3f
|
||||
NONCE: fdf6b0229e4bcc2a
|
||||
IN: 2ba91904c143be99297b39f52856904af41705c176c8c6554b6bc89bddffbcc1
|
||||
AD: 3539d9dd821f004f4ced1637071f4be6abd7fe98f017f0a8ce3f49dc8d496f46
|
||||
CT: ff9d6d924e737a1df8c2bd3047e40ab401f903aa0e5b51acb991bac38ac2cc4d
|
||||
TAG: 1bcaa415a6a3c7
|
||||
|
||||
KEY: 6d65e627cab6d5eb1a088b25bd6c3a8a004a7a19cccae909d62fed3559c812f7
|
||||
NONCE: 7ff00a8798b792de
|
||||
IN: 6848ee4ac820291a2e1dc3baad97f1ad8b7160dfeaa1bc83b2700ae42b5a366b
|
||||
AD: d2437b1306bf0ea211449fac863ca0d1074d84caee9009c5d54b9e9bdc8de6b1
|
||||
CT: 2da0abe2a71e1c0b1ab309c160a8cebe45c6e16170aa5561806484ba2b5b9a9a
|
||||
TAG: 566003e1f78d2a90
|
||||
|
||||
KEY: 63401046a96efbc8c6483a2c396b2a593d3fae0db565525b85999fae13a46b6a
|
||||
NONCE: 051393d775e635ee
|
||||
IN: 2b4b6477580382aae782f8b5772c0948a444d8d95caacd85c0856c7e4393fe09
|
||||
AD: 3d84d2e70e9c062d1f511eb685a9a90c8d5fa50eadf8455c7148666b3e7155e0
|
||||
CT: 880c1123e54fd8ffb3c293720dd174913572e619ef46504cdaa64fc451b0ec1c
|
||||
TAG: 339274339c88d50ac0
|
||||
|
||||
KEY: 291fccfce0782f1787d62d4b9293d2ada4c04d37a8288ba9ba9aae0d31aad204
|
||||
NONCE: 7450bbd62e4aba7b
|
||||
IN: adc251e793181e5d4c4bd983b853eb13f2096ccb340996b6eca4cd2157efcec7
|
||||
AD: 4c598f6deedc8c1d97da33654763495cca3517430eec4edb006b10c95e031ae6
|
||||
CT: 28bda22e4922cd8ff6739cd8a6bdafce036d9c61a145a65ca1b86f6d4d3206a1
|
||||
TAG: d98fd43fe7ac74d4b016
|
||||
|
||||
KEY: fa3a9674d4a0eb36b2f7547c956443d09e6b4e4acfc9deda838eb7ebdb999a8d
|
||||
NONCE: 0a2572592c3bbbf6
|
||||
IN: ae27f70fda9f5a5be0f704a27f0b8a9c04ce83d3c2e0d7ec152da25f473b0c8a
|
||||
AD: 6ee8705a9a3655d198497ad410da02005872ecbe397824851b80f4050bfdd311
|
||||
CT: f356cbd88e4e2aff62d91e3f914032085388955bbba995fde013758b8702e38f
|
||||
TAG: 00324c76fecd3f50e1e3b8
|
||||
|
||||
KEY: 471ec87b992b104d369748d96856b5f66149cb45ca05c17f29d24eb9526fe6db
|
||||
NONCE: 23a2df9ed0b47439
|
||||
IN: 2b9452bca0f48e5519ec3d0736597608df6ad9ce799eba913cff71573d79c092
|
||||
AD: a56722ddfaee5f1b64398c225ee8bcdcfde5c2127101c363bfac52bc409c1082
|
||||
CT: 7bbc464aac5dd29c25262fe0b116c176d827c2cc8dd63428393b0a9110f3c194
|
||||
TAG: 2e87f4a6663a62e47c7e197f
|
||||
|
||||
KEY: a29d1cfd4ccdc18803fbca9500f4bb29ce99cfcbf8acc41b8208dae4b7ee5d64
|
||||
NONCE: 634f99e88e237ef0
|
||||
IN: 09ee5982c5743f396d0c29c13e3fbb8fb89f61705da05466291e010effd51a5c
|
||||
AD: 564dddfcc3227b413244f1105b610f192decf15c4cfa067f4d7fcd6bd7af11b8
|
||||
CT: 32916b67a6f32733623344c98c49773f3e721dc2ded105fb245799525bc9c84c
|
||||
TAG: ff463c07e7ef831321d3fd775f
|
||||
|
||||
KEY: 08ba23616d911188f91da063278bef1237dcbf17f52585e53c2c4b6cf3ac9f0d
|
||||
NONCE: 989ae593eddd3874
|
||||
IN: 749152c9478944c8271c0c11e07bc1c569eec01493e65b3b94842a1bf5d721f8
|
||||
AD: a12d1a45b7c9b91ab08751a70b753714052ad24e0b2619fe8c3be303c65f2dbc
|
||||
CT: 34c40538ee1d22ddf8ac290dd7d423dfc622b5cf8f3412a5343e277822aea713
|
||||
TAG: 014c7c678e0949e88071d1fe3531
|
||||
|
||||
KEY: c2ba8bed8634156afc6bfe3754c91744d4131de39d059f3a866399f916553b5c
|
||||
NONCE: 80fbf7b433a4cd9c
|
||||
IN: 419be6623e7964f9f26068dd969e4a139617e67c5ffb269b3013c433fe771c77
|
||||
AD: 3937592db78a61ff469691b6800792019bc2b3d42512f23c1b1a66a8274495cb
|
||||
CT: 9d5bd1c7e766763eb00684c038043111d8c6390a8d6e17a15ef97c02ab16f09c
|
||||
TAG: a64d0eeb4a01481ec0cee8c1c357e3
|
||||
|
||||
@@ -47,8 +47,8 @@ AD: "123456789abcdef0"
|
||||
CT: e275aeb341e1fc9a70c4fd4496fc7cdb
|
||||
TAG: 41acd0560ea6843d3e5d4e5babf6e946
|
||||
|
||||
# Test vectors from chacha20_poly1305_deprecated_tests.txt, modified for the
|
||||
# RFC 7539 AEAD construction.
|
||||
# Test vectors from chacha20_poly1305_old_tests.txt, modified for the RFC 7539
|
||||
# AEAD construction.
|
||||
|
||||
KEY: 9a97f65b9b4c721b960a672145fca8d4e32e67f9111ea979ce9c4826806aeee6
|
||||
NONCE: 000000003de9c0da2bd7f91e
|
||||
@@ -470,5 +470,109 @@ AD: fd6a3fdd879f8880843eac20ae01c1b9dc3487d270a806572088ef2ddc1f1e0de495e71d4813
|
||||
CT: bd11ed07b7b4b30eeaf25d6a41a549cca0a5aee71f990ac566a37265d7af2ce3c03703427ee0b2755c2bdfc29f9d826aec6ee4ad28af48079ac23db16580b97424f3a4e35cc23625d39f95699d9ff5143e9a2bc26fcfee4f125f5aa2d968ccfc2faaf9db3c28850f6757f735cbc50c94c498bcde4f23bffafa8dd5f70d1a011e35eb26e905d4e68848fedebeb197be595c085ba33f11ba8398258445051751888e9bba111f800f31b37c447074ca6dce6d54b4dfad6cee5138643d4f6ac045e8047248924e88ea4294c7878bc22c9b41924ce301f22693c33733107bf1ba85e34806c5e4366ea66fc52a5f89dd9bf213239158b3d4d2600dde696c61d76c398b9bf10de9118e812e891c8f3355c0ecc6405f79bc32a58905e37888a1d8395fbedc3ac54eca569f
|
||||
TAG: 296a397d280d026fc3627f4718971be9
|
||||
|
||||
# BoringSSL has additional tests here for truncated tags. *ring* doesn't
|
||||
# support tag truncation, so those tests were removed.
|
||||
# Tag truncation tests.
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c2
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f3
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f37465
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a84
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a8413
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a841386
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a84138648
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a84138648a5
|
||||
|
||||
KEY: c66e89fbab01208f6a60847f4f34b38d27b554c119cf8d9e0b118aa7266ab865
|
||||
NONCE: 000000005d9856060c54ab06
|
||||
IN: f9e3e9b5ed07b2080db8c1ffc37e4a6cb3cd544608921e18610d00b17c6e
|
||||
AD: 85c112a1efe0a20ef3a550526a7afbc98f6367ebbede4e703099abd78f51
|
||||
CT: b5cc754f6dd19ef2d66f90e6bc9a322ddf216ef248cbe76b5ab6dd53bc36
|
||||
TAG: d3f7b9c295f374651a84138648a591
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ unsigned long getauxval(unsigned long type) __attribute__((weak));
|
||||
|
||||
extern uint32_t OPENSSL_armcap_P;
|
||||
|
||||
char CRYPTO_is_NEON_capable(void) {
|
||||
char CRYPTO_is_NEON_capable_at_runtime(void) {
|
||||
return (OPENSSL_armcap_P & ARMV7_NEON) != 0;
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -14,6 +14,8 @@
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
@@ -86,22 +88,22 @@ uint32_t OPENSSL_armcap_P = ARMV7_NEON_FUNCTIONAL;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(OPENSSL_WINDOWS)
|
||||
#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER)
|
||||
#define OPENSSL_CDECL __cdecl
|
||||
#else
|
||||
#define OPENSSL_CDECL
|
||||
#endif
|
||||
|
||||
#if !defined(BORINGSSL_NO_STATIC_INITIALIZER)
|
||||
#if !defined(OPENSSL_WINDOWS)
|
||||
static void do_library_init(void) __attribute__ ((constructor));
|
||||
#else
|
||||
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
|
||||
static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
|
||||
#elif defined(OPENSSL_WINDOWS)
|
||||
#pragma section(".CRT$XCU", read)
|
||||
static void __cdecl do_library_init(void);
|
||||
__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) =
|
||||
do_library_init;
|
||||
#else
|
||||
static void do_library_init(void) __attribute__ ((constructor));
|
||||
#endif
|
||||
#endif /* !BORINGSSL_NO_STATIC_INITIALIZER */
|
||||
|
||||
/* do_library_init is the actual initialization function. If
|
||||
* BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static
|
||||
@@ -117,9 +119,9 @@ static void OPENSSL_CDECL do_library_init(void) {
|
||||
void CRYPTO_library_init(void) {
|
||||
/* TODO(davidben): It would be tidier if this build knob could be replaced
|
||||
* with an internal lazy-init mechanism that would handle things correctly
|
||||
* in-library. */
|
||||
* in-library. https://crbug.com/542879 */
|
||||
#if defined(BORINGSSL_NO_STATIC_INITIALIZER)
|
||||
do_library_init();
|
||||
CRYPTO_once(&once, do_library_init);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
include_directories(../../include)
|
||||
|
||||
if (${ARCH} STREQUAL "arm")
|
||||
set(
|
||||
CURVE25519_ARCH_SOURCES
|
||||
|
||||
asm/x25519-arm.S
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
curve25519
|
||||
|
||||
OBJECT
|
||||
|
||||
curve25519.c
|
||||
|
||||
${CURVE25519_ARCH_SOURCES}
|
||||
)
|
||||
|
||||
add_executable(
|
||||
ed25519_test
|
||||
|
||||
ed25519_test.cc
|
||||
$<TARGET_OBJECTS:test_support>
|
||||
)
|
||||
|
||||
target_link_libraries(ed25519_test crypto)
|
||||
add_dependencies(all_tests ed25519_test)
|
||||
|
||||
add_executable(
|
||||
x25519_test
|
||||
|
||||
x25519_test.cc
|
||||
)
|
||||
|
||||
target_link_libraries(x25519_test crypto)
|
||||
add_dependencies(all_tests x25519_test)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
/* 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/curve25519.h>
|
||||
|
||||
#include "../test/file_test.h"
|
||||
|
||||
|
||||
static bool TestSignature(FileTest *t, void *arg) {
|
||||
std::vector<uint8_t> private_key, public_key, message, expected_signature;
|
||||
if (!t->GetBytes(&private_key, "PRIV") ||
|
||||
private_key.size() != 64 ||
|
||||
!t->GetBytes(&public_key, "PUB") ||
|
||||
public_key.size() != 32 ||
|
||||
!t->GetBytes(&message, "MESSAGE") ||
|
||||
!t->GetBytes(&expected_signature, "SIG") ||
|
||||
expected_signature.size() != 64) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t signature[64];
|
||||
if (!ED25519_sign(signature, message.data(), message.size(),
|
||||
private_key.data())) {
|
||||
t->PrintLine("ED25519_sign failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!t->ExpectBytesEqual(expected_signature.data(), expected_signature.size(),
|
||||
signature, sizeof(signature))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ED25519_verify(message.data(), message.size(), signature,
|
||||
public_key.data())) {
|
||||
t->PrintLine("ED25519_verify failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s <test input.txt>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return FileTestMain(TestSignature, nullptr, argv[1]);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,128 @@
|
||||
/* 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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/curve25519.h>
|
||||
|
||||
|
||||
static bool TestX25519() {
|
||||
/* Taken from
|
||||
* https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
|
||||
static const uint8_t kScalar1[32] = {
|
||||
0xa5, 0x46, 0xe3, 0x6b, 0xf0, 0x52, 0x7c, 0x9d, 0x3b, 0x16, 0x15,
|
||||
0x4b, 0x82, 0x46, 0x5e, 0xdd, 0x62, 0x14, 0x4c, 0x0a, 0xc1, 0xfc,
|
||||
0x5a, 0x18, 0x50, 0x6a, 0x22, 0x44, 0xba, 0x44, 0x9a, 0xc4,
|
||||
};
|
||||
static const uint8_t kPoint1[32] = {
|
||||
0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94, 0xc1,
|
||||
0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec, 0x26, 0xb3,
|
||||
0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab, 0x1c, 0x4c,
|
||||
};
|
||||
|
||||
uint8_t out[32];
|
||||
X25519(out, kScalar1, kPoint1);
|
||||
|
||||
static const uint8_t kExpected1[32] = {
|
||||
0xc3, 0xda, 0x55, 0x37, 0x9d, 0xe9, 0xc6, 0x90, 0x8e, 0x94, 0xea,
|
||||
0x4d, 0xf2, 0x8d, 0x08, 0x4f, 0x32, 0xec, 0xcf, 0x03, 0x49, 0x1c,
|
||||
0x71, 0xf7, 0x54, 0xb4, 0x07, 0x55, 0x77, 0xa2, 0x85, 0x52,
|
||||
};
|
||||
if (memcmp(kExpected1, out, sizeof(out)) != 0) {
|
||||
fprintf(stderr, "X25519 test one failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static const uint8_t kScalar2[32] = {
|
||||
0x4b, 0x66, 0xe9, 0xd4, 0xd1, 0xb4, 0x67, 0x3c, 0x5a, 0xd2, 0x26,
|
||||
0x91, 0x95, 0x7d, 0x6a, 0xf5, 0xc1, 0x1b, 0x64, 0x21, 0xe0, 0xea,
|
||||
0x01, 0xd4, 0x2c, 0xa4, 0x16, 0x9e, 0x79, 0x18, 0xba, 0x0d,
|
||||
};
|
||||
static const uint8_t kPoint2[32] = {
|
||||
0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7, 0x95,
|
||||
0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10, 0x6f, 0xc0,
|
||||
0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15, 0xa4, 0x93,
|
||||
};
|
||||
|
||||
X25519(out, kScalar2, kPoint2);
|
||||
|
||||
static const uint8_t kExpected2[32] = {
|
||||
0x95, 0xcb, 0xde, 0x94, 0x76, 0xe8, 0x90, 0x7d, 0x7a, 0xad, 0xe4,
|
||||
0x5c, 0xb4, 0xb8, 0x73, 0xf8, 0x8b, 0x59, 0x5a, 0x68, 0x79, 0x9f,
|
||||
0xa1, 0x52, 0xe6, 0xf8, 0xf7, 0x64, 0x7a, 0xac, 0x79, 0x57,
|
||||
};
|
||||
if (memcmp(kExpected2, out, sizeof(out)) != 0) {
|
||||
fprintf(stderr, "X25519 test two failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestX25519SmallOrder() {
|
||||
static const uint8_t kSmallOrderPoint[32] = {
|
||||
0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3,
|
||||
0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32,
|
||||
0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8,
|
||||
};
|
||||
|
||||
uint8_t out[32], private_key[32];
|
||||
memset(private_key, 0x11, sizeof(private_key));
|
||||
|
||||
if (X25519(out, private_key, kSmallOrderPoint)) {
|
||||
fprintf(stderr, "X25519 returned success with a small-order input.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestX25519Iterated() {
|
||||
/* Taken from
|
||||
* https://tools.ietf.org/html/draft-irtf-cfrg-curves-11#section-5.2 */
|
||||
uint8_t scalar[32] = {9}, point[32] = {9}, out[32];
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < 1000; i++) {
|
||||
X25519(out, scalar, point);
|
||||
memcpy(point, scalar, sizeof(point));
|
||||
memcpy(scalar, out, sizeof(scalar));
|
||||
}
|
||||
|
||||
static const uint8_t kExpected[32] = {
|
||||
0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55, 0x28, 0x00, 0xef,
|
||||
0x56, 0x6f, 0x2f, 0x4d, 0x3c, 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60,
|
||||
0xe3, 0x87, 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51,
|
||||
};
|
||||
|
||||
if (memcmp(kExpected, scalar, sizeof(kExpected)) != 0) {
|
||||
fprintf(stderr, "Iterated X25519 test failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (!TestX25519() ||
|
||||
!TestX25519Iterated() ||
|
||||
!TestX25519SmallOrder()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -202,24 +202,7 @@ how to use xors :-) I got it to its final state.
|
||||
#define ITERATIONS 16
|
||||
#define HALF_ITERATIONS 8
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ROTATE(a, n) (_lrotr(a, n))
|
||||
#elif defined(__ICC)
|
||||
#define ROTATE(a, n) (_rotr(a, n))
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) && \
|
||||
!defined(__STRICT_ANSI__) && \
|
||||
(defined(OPENSSL_X86) || defined(OPENSSL_X86_64))
|
||||
#define ROTATE(a, n) \
|
||||
({ \
|
||||
unsigned int ret; \
|
||||
asm("rorl %1,%0" : "=r"(ret) : "I"(n), "0"(a) : "cc"); \
|
||||
ret; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifndef ROTATE
|
||||
#define ROTATE(a, n) (((a) >> (n)) + ((a) << (32 - (n))))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
+4
-8
@@ -85,11 +85,7 @@ DH *DH_new(void) {
|
||||
CRYPTO_MUTEX_init(&dh->method_mont_p_lock);
|
||||
|
||||
dh->references = 1;
|
||||
if (!CRYPTO_new_ex_data(&g_ex_data_class, dh, &dh->ex_data)) {
|
||||
CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock);
|
||||
OPENSSL_free(dh);
|
||||
return NULL;
|
||||
}
|
||||
CRYPTO_new_ex_data(&dh->ex_data);
|
||||
|
||||
return dh;
|
||||
}
|
||||
@@ -448,11 +444,11 @@ DH *DHparams_dup(const DH *dh) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
|
||||
int index;
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
|
||||
dup_func, free_func)) {
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
|
||||
free_func)) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
|
||||
+119
-132
@@ -55,182 +55,169 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../bn/internal.h"
|
||||
|
||||
|
||||
#if BN_BITS2 == 32
|
||||
#define TOBN(lo, hi) lo, hi
|
||||
#elif BN_BITS2 == 64
|
||||
#define TOBN(lo, hi) ((BN_ULONG)hi << 32 | lo)
|
||||
#else
|
||||
#error "unsupported BN_BITS2"
|
||||
#endif
|
||||
|
||||
static const BN_ULONG dh1024_160_p[] = {
|
||||
TOBN(0x2E4A4371, 0xDF1FB2BC), TOBN(0x6D4DA708, 0xE68CFDA7),
|
||||
TOBN(0x365C1A65, 0x45BF37DF), TOBN(0x0DC8B4BD, 0xA151AF5F),
|
||||
TOBN(0xF55BCCC0, 0xFAA31A4F), TOBN(0xE5644738, 0x4EFFD6FA),
|
||||
TOBN(0x219A7372, 0x98488E9C), TOBN(0x90C4BD70, 0xACCBDD7D),
|
||||
TOBN(0xD49B83BF, 0x24975C3C), TOBN(0xA9061123, 0x13ECB4AE),
|
||||
TOBN(0x2EE652C0, 0x9838EF1E), TOBN(0x75A23D18, 0x6073E286),
|
||||
TOBN(0x52D23B61, 0x9A6A9DCA), TOBN(0xFB06A3C6, 0x52C99FBC),
|
||||
TOBN(0xAE5D54EC, 0xDE92DE5E), TOBN(0xA080E01D, 0xB10B8F96),
|
||||
TOBN(0xDF1FB2BC, 0x2E4A4371), TOBN(0xE68CFDA7, 0x6D4DA708),
|
||||
TOBN(0x45BF37DF, 0x365C1A65), TOBN(0xA151AF5F, 0x0DC8B4BD),
|
||||
TOBN(0xFAA31A4F, 0xF55BCCC0), TOBN(0x4EFFD6FA, 0xE5644738),
|
||||
TOBN(0x98488E9C, 0x219A7372), TOBN(0xACCBDD7D, 0x90C4BD70),
|
||||
TOBN(0x24975C3C, 0xD49B83BF), TOBN(0x13ECB4AE, 0xA9061123),
|
||||
TOBN(0x9838EF1E, 0x2EE652C0), TOBN(0x6073E286, 0x75A23D18),
|
||||
TOBN(0x9A6A9DCA, 0x52D23B61), TOBN(0x52C99FBC, 0xFB06A3C6),
|
||||
TOBN(0xDE92DE5E, 0xAE5D54EC), TOBN(0xB10B8F96, 0xA080E01D),
|
||||
};
|
||||
static const BN_ULONG dh1024_160_g[] = {
|
||||
TOBN(0x22B3B2E5, 0x855E6EEB), TOBN(0xF97C2A24, 0x858F4DCE),
|
||||
TOBN(0x18D08BC8, 0x2D779D59), TOBN(0x8E73AFA3, 0xD662A4D1),
|
||||
TOBN(0x69B6A28A, 0x1DBF0A01), TOBN(0x7A091F53, 0xA6A24C08),
|
||||
TOBN(0x63F80A76, 0x909D0D22), TOBN(0xB9A92EE1, 0xD7FBD7D3),
|
||||
TOBN(0x9E2749F4, 0x5E91547F), TOBN(0xB01B886A, 0x160217B4),
|
||||
TOBN(0x5504F213, 0x777E690F), TOBN(0x5C41564B, 0x266FEA1E),
|
||||
TOBN(0x14266D31, 0xD6406CFF), TOBN(0x58AC507F, 0xF8104DD2),
|
||||
TOBN(0xEFB99905, 0x6765A442), TOBN(0xC3FD3412, 0xA4D1CBD5),
|
||||
TOBN(0x855E6EEB, 0x22B3B2E5), TOBN(0x858F4DCE, 0xF97C2A24),
|
||||
TOBN(0x2D779D59, 0x18D08BC8), TOBN(0xD662A4D1, 0x8E73AFA3),
|
||||
TOBN(0x1DBF0A01, 0x69B6A28A), TOBN(0xA6A24C08, 0x7A091F53),
|
||||
TOBN(0x909D0D22, 0x63F80A76), TOBN(0xD7FBD7D3, 0xB9A92EE1),
|
||||
TOBN(0x5E91547F, 0x9E2749F4), TOBN(0x160217B4, 0xB01B886A),
|
||||
TOBN(0x777E690F, 0x5504F213), TOBN(0x266FEA1E, 0x5C41564B),
|
||||
TOBN(0xD6406CFF, 0x14266D31), TOBN(0xF8104DD2, 0x58AC507F),
|
||||
TOBN(0x6765A442, 0xEFB99905), TOBN(0xA4D1CBD5, 0xC3FD3412),
|
||||
};
|
||||
static const BN_ULONG dh1024_160_q[] = {
|
||||
TOBN(0x49462353, 0x64B7CB9D), TOBN(0x8ABA4E7D, 0x81A8DF27), 0xF518AA87,
|
||||
TOBN(0x64B7CB9D, 0x49462353), TOBN(0x81A8DF27, 0x8ABA4E7D), 0xF518AA87,
|
||||
};
|
||||
|
||||
static const BN_ULONG dh2048_224_p[] = {
|
||||
TOBN(0x0C10E64F, 0x0AC4DFFE), TOBN(0x4E71B81C, 0xCF9DE538),
|
||||
TOBN(0xFFA31F71, 0x7EF363E2), TOBN(0x6B8E75B9, 0xE3FB73C1),
|
||||
TOBN(0x4BA80A29, 0xC9B53DCF), TOBN(0x16E79763, 0x23F10B0E),
|
||||
TOBN(0x13042E9B, 0xC52172E4), TOBN(0xC928B2B9, 0xBE60E69C),
|
||||
TOBN(0xB9E587E8, 0x80CD86A1), TOBN(0x98C641A4, 0x315D75E1),
|
||||
TOBN(0x44328387, 0xCDF93ACC), TOBN(0xDC0A486D, 0x15987D9A),
|
||||
TOBN(0x1FD5A074, 0x7310F712), TOBN(0xDE31EFDC, 0x278273C7),
|
||||
TOBN(0x415D9330, 0x1602E714), TOBN(0xBC8985DB, 0x81286130),
|
||||
TOBN(0x70918836, 0xB3BF8A31), TOBN(0xB9C49708, 0x6A00E0A0),
|
||||
TOBN(0x8BBC27BE, 0xC6BA0B2C), TOBN(0xED34DBF6, 0xC9F98D11),
|
||||
TOBN(0xB6C12207, 0x7AD5B7D0), TOBN(0x55B7394B, 0xD91E8FEF),
|
||||
TOBN(0xEFDA4DF8, 0x9037C9ED), TOBN(0xAD6AC212, 0x6D3F8152),
|
||||
TOBN(0x1274A0A6, 0x1DE6B85A), TOBN(0x309C180E, 0xEB3D688A),
|
||||
TOBN(0x7BA1DF15, 0xAF9A3C40), TOBN(0xF95A56DB, 0xE6FA141D),
|
||||
TOBN(0xB61D0A75, 0xB54B1597), TOBN(0x683B9FD1, 0xA20D64E5),
|
||||
TOBN(0x9559C51F, 0xD660FAA7), TOBN(0x9123A9D0, 0xAD107E1E),
|
||||
TOBN(0x0AC4DFFE, 0x0C10E64F), TOBN(0xCF9DE538, 0x4E71B81C),
|
||||
TOBN(0x7EF363E2, 0xFFA31F71), TOBN(0xE3FB73C1, 0x6B8E75B9),
|
||||
TOBN(0xC9B53DCF, 0x4BA80A29), TOBN(0x23F10B0E, 0x16E79763),
|
||||
TOBN(0xC52172E4, 0x13042E9B), TOBN(0xBE60E69C, 0xC928B2B9),
|
||||
TOBN(0x80CD86A1, 0xB9E587E8), TOBN(0x315D75E1, 0x98C641A4),
|
||||
TOBN(0xCDF93ACC, 0x44328387), TOBN(0x15987D9A, 0xDC0A486D),
|
||||
TOBN(0x7310F712, 0x1FD5A074), TOBN(0x278273C7, 0xDE31EFDC),
|
||||
TOBN(0x1602E714, 0x415D9330), TOBN(0x81286130, 0xBC8985DB),
|
||||
TOBN(0xB3BF8A31, 0x70918836), TOBN(0x6A00E0A0, 0xB9C49708),
|
||||
TOBN(0xC6BA0B2C, 0x8BBC27BE), TOBN(0xC9F98D11, 0xED34DBF6),
|
||||
TOBN(0x7AD5B7D0, 0xB6C12207), TOBN(0xD91E8FEF, 0x55B7394B),
|
||||
TOBN(0x9037C9ED, 0xEFDA4DF8), TOBN(0x6D3F8152, 0xAD6AC212),
|
||||
TOBN(0x1DE6B85A, 0x1274A0A6), TOBN(0xEB3D688A, 0x309C180E),
|
||||
TOBN(0xAF9A3C40, 0x7BA1DF15), TOBN(0xE6FA141D, 0xF95A56DB),
|
||||
TOBN(0xB54B1597, 0xB61D0A75), TOBN(0xA20D64E5, 0x683B9FD1),
|
||||
TOBN(0xD660FAA7, 0x9559C51F), TOBN(0xAD107E1E, 0x9123A9D0),
|
||||
};
|
||||
|
||||
static const BN_ULONG dh2048_224_g[] = {
|
||||
TOBN(0x191F2BFA, 0x84B890D3), TOBN(0x2A7065B3, 0x81BC087F),
|
||||
TOBN(0xF6EC0179, 0x19C418E1), TOBN(0x71CFFF4C, 0x7B5A0F1C),
|
||||
TOBN(0x9B6AA4BD, 0xEDFE72FE), TOBN(0x94B30269, 0x81E1BCFE),
|
||||
TOBN(0x8D6C0191, 0x566AFBB4), TOBN(0x409D13CD, 0xB539CCE3),
|
||||
TOBN(0x5F2FF381, 0x6AA21E7F), TOBN(0x770589EF, 0xD9E263E4),
|
||||
TOBN(0xD19963DD, 0x10E183ED), TOBN(0x150B8EEB, 0xB70A8137),
|
||||
TOBN(0x28C8F8AC, 0x051AE3D4), TOBN(0x0C1AB15B, 0xBB77A86F),
|
||||
TOBN(0x16A330EF, 0x6E3025E3), TOBN(0xD6F83456, 0x19529A45),
|
||||
TOBN(0x118E98D1, 0xF180EB34), TOBN(0x50717CBE, 0xB5F6C6B2),
|
||||
TOBN(0xDA7460CD, 0x09939D54), TOBN(0x22EA1ED4, 0xE2471504),
|
||||
TOBN(0x521BC98A, 0xB8A762D0), TOBN(0x5AC1348B, 0xF4D02727),
|
||||
TOBN(0x1999024A, 0xC1766910), TOBN(0xA8D66AD7, 0xBE5E9001),
|
||||
TOBN(0x620A8652, 0xC57DB17C), TOBN(0x00C29F52, 0xAB739D77),
|
||||
TOBN(0xA70C4AFA, 0xDD921F01), TOBN(0x10B9A6F0, 0xA6824A4E),
|
||||
TOBN(0xCFE4FFE3, 0x74866A08), TOBN(0x89998CAF, 0x6CDEBE7B),
|
||||
TOBN(0x8FFDAC50, 0x9DF30B5C), TOBN(0x4F2D9AE3, 0xAC4032EF),
|
||||
TOBN(0x84B890D3, 0x191F2BFA), TOBN(0x81BC087F, 0x2A7065B3),
|
||||
TOBN(0x19C418E1, 0xF6EC0179), TOBN(0x7B5A0F1C, 0x71CFFF4C),
|
||||
TOBN(0xEDFE72FE, 0x9B6AA4BD), TOBN(0x81E1BCFE, 0x94B30269),
|
||||
TOBN(0x566AFBB4, 0x8D6C0191), TOBN(0xB539CCE3, 0x409D13CD),
|
||||
TOBN(0x6AA21E7F, 0x5F2FF381), TOBN(0xD9E263E4, 0x770589EF),
|
||||
TOBN(0x10E183ED, 0xD19963DD), TOBN(0xB70A8137, 0x150B8EEB),
|
||||
TOBN(0x051AE3D4, 0x28C8F8AC), TOBN(0xBB77A86F, 0x0C1AB15B),
|
||||
TOBN(0x6E3025E3, 0x16A330EF), TOBN(0x19529A45, 0xD6F83456),
|
||||
TOBN(0xF180EB34, 0x118E98D1), TOBN(0xB5F6C6B2, 0x50717CBE),
|
||||
TOBN(0x09939D54, 0xDA7460CD), TOBN(0xE2471504, 0x22EA1ED4),
|
||||
TOBN(0xB8A762D0, 0x521BC98A), TOBN(0xF4D02727, 0x5AC1348B),
|
||||
TOBN(0xC1766910, 0x1999024A), TOBN(0xBE5E9001, 0xA8D66AD7),
|
||||
TOBN(0xC57DB17C, 0x620A8652), TOBN(0xAB739D77, 0x00C29F52),
|
||||
TOBN(0xDD921F01, 0xA70C4AFA), TOBN(0xA6824A4E, 0x10B9A6F0),
|
||||
TOBN(0x74866A08, 0xCFE4FFE3), TOBN(0x6CDEBE7B, 0x89998CAF),
|
||||
TOBN(0x9DF30B5C, 0x8FFDAC50), TOBN(0xAC4032EF, 0x4F2D9AE3),
|
||||
};
|
||||
|
||||
static const BN_ULONG dh2048_224_q[] = {
|
||||
TOBN(0xB36371EB, 0xBF389A99), TOBN(0x4738CEBC, 0x1F80535A),
|
||||
TOBN(0x99717710, 0xC58D93FE), 0x801C0D34,
|
||||
TOBN(0xBF389A99, 0xB36371EB), TOBN(0x1F80535A, 0x4738CEBC),
|
||||
TOBN(0xC58D93FE, 0x99717710), 0x801C0D34,
|
||||
};
|
||||
|
||||
static const BN_ULONG dh2048_256_p[] = {
|
||||
TOBN(0x1E1A1597, 0xDB094AE9), TOBN(0xD7EF09CA, 0x693877FA),
|
||||
TOBN(0x6E11715F, 0x6116D227), TOBN(0xC198AF12, 0xA4B54330),
|
||||
TOBN(0xD7014103, 0x75F26375), TOBN(0x54E710C3, 0xC3A3960A),
|
||||
TOBN(0xBD0BE621, 0xDED4010A), TOBN(0x89962856, 0xC0B857F6),
|
||||
TOBN(0x71506026, 0xB3CA3F79), TOBN(0xE6B486F6, 0x1CCACB83),
|
||||
TOBN(0x14056425, 0x67E144E5), TOBN(0xA41825D9, 0xF6A167B5),
|
||||
TOBN(0x96524D8E, 0x3AD83477), TOBN(0x51BFA4AB, 0xF13C6D9A),
|
||||
TOBN(0x35488A0E, 0x2D525267), TOBN(0xCAA6B790, 0xB63ACAE1),
|
||||
TOBN(0x81B23F76, 0x4FDB70C5), TOBN(0x12307F5C, 0xBC39A0BF),
|
||||
TOBN(0xB1E59BB8, 0xB941F54E), TOBN(0xD45F9088, 0x6C5BFC11),
|
||||
TOBN(0x4275BF7B, 0x22E0B1EF), TOBN(0x5B4758C0, 0x91F9E672),
|
||||
TOBN(0x6BCF67ED, 0x5A8A9D30), TOBN(0x97517ABD, 0x209E0C64),
|
||||
TOBN(0x830E9A7C, 0x3BF4296D), TOBN(0x34096FAA, 0x16C3D911),
|
||||
TOBN(0x61B2AA30, 0xFAF7DF45), TOBN(0xD61957D4, 0xE00DF8F1),
|
||||
TOBN(0x435E3B00, 0x5D2CEED4), TOBN(0x660DD0F2, 0x8CEEF608),
|
||||
TOBN(0x65195999, 0xFFBBD19C), TOBN(0xB4B6663C, 0x87A8E61D),
|
||||
TOBN(0xDB094AE9, 0x1E1A1597), TOBN(0x693877FA, 0xD7EF09CA),
|
||||
TOBN(0x6116D227, 0x6E11715F), TOBN(0xA4B54330, 0xC198AF12),
|
||||
TOBN(0x75F26375, 0xD7014103), TOBN(0xC3A3960A, 0x54E710C3),
|
||||
TOBN(0xDED4010A, 0xBD0BE621), TOBN(0xC0B857F6, 0x89962856),
|
||||
TOBN(0xB3CA3F79, 0x71506026), TOBN(0x1CCACB83, 0xE6B486F6),
|
||||
TOBN(0x67E144E5, 0x14056425), TOBN(0xF6A167B5, 0xA41825D9),
|
||||
TOBN(0x3AD83477, 0x96524D8E), TOBN(0xF13C6D9A, 0x51BFA4AB),
|
||||
TOBN(0x2D525267, 0x35488A0E), TOBN(0xB63ACAE1, 0xCAA6B790),
|
||||
TOBN(0x4FDB70C5, 0x81B23F76), TOBN(0xBC39A0BF, 0x12307F5C),
|
||||
TOBN(0xB941F54E, 0xB1E59BB8), TOBN(0x6C5BFC11, 0xD45F9088),
|
||||
TOBN(0x22E0B1EF, 0x4275BF7B), TOBN(0x91F9E672, 0x5B4758C0),
|
||||
TOBN(0x5A8A9D30, 0x6BCF67ED), TOBN(0x209E0C64, 0x97517ABD),
|
||||
TOBN(0x3BF4296D, 0x830E9A7C), TOBN(0x16C3D911, 0x34096FAA),
|
||||
TOBN(0xFAF7DF45, 0x61B2AA30), TOBN(0xE00DF8F1, 0xD61957D4),
|
||||
TOBN(0x5D2CEED4, 0x435E3B00), TOBN(0x8CEEF608, 0x660DD0F2),
|
||||
TOBN(0xFFBBD19C, 0x65195999), TOBN(0x87A8E61D, 0xB4B6663C),
|
||||
};
|
||||
static const BN_ULONG dh2048_256_g[] = {
|
||||
TOBN(0x6CC41659, 0x664B4C0F), TOBN(0xEF98C582, 0x5E2327CF),
|
||||
TOBN(0xD4795451, 0xD647D148), TOBN(0x90F00EF8, 0x2F630784),
|
||||
TOBN(0x1DB246C3, 0x184B523D), TOBN(0xCDC67EB6, 0xC7891428),
|
||||
TOBN(0x0DF92B52, 0x7FD02837), TOBN(0x64E0EC37, 0xB3353BBB),
|
||||
TOBN(0x57CD0915, 0xECD06E15), TOBN(0xDF016199, 0xB7D2BBD2),
|
||||
TOBN(0x052588B9, 0xC8484B1E), TOBN(0x13D3FE14, 0xDB2A3B73),
|
||||
TOBN(0xD182EA0A, 0xD052B985), TOBN(0xE83B9C80, 0xA4BD1BFF),
|
||||
TOBN(0xFB3F2E55, 0xDFC967C1), TOBN(0x767164E1, 0xB5045AF2),
|
||||
TOBN(0x6F2F9193, 0x1D14348F), TOBN(0x428EBC83, 0x64E67982),
|
||||
TOBN(0x82D6ED38, 0x8AC376D2), TOBN(0xAAB8A862, 0x777DE62A),
|
||||
TOBN(0xE9EC144B, 0xDDF463E5), TOBN(0xC77A57F2, 0x0196F931),
|
||||
TOBN(0x41000A65, 0xA55AE313), TOBN(0xC28CBB18, 0x901228F8),
|
||||
TOBN(0x7E8C6F62, 0xBC3773BF), TOBN(0x0C6B47B1, 0xBE3A6C1B),
|
||||
TOBN(0xAC0BB555, 0xFF4FED4A), TOBN(0x77BE463F, 0x10DBC150),
|
||||
TOBN(0x1A0BA125, 0x07F4793A), TOBN(0x21EF2054, 0x4CA7B18F),
|
||||
TOBN(0x60EDBD48, 0x2E775066), TOBN(0x73134D0B, 0x3FB32C9B),
|
||||
TOBN(0x664B4C0F, 0x6CC41659), TOBN(0x5E2327CF, 0xEF98C582),
|
||||
TOBN(0xD647D148, 0xD4795451), TOBN(0x2F630784, 0x90F00EF8),
|
||||
TOBN(0x184B523D, 0x1DB246C3), TOBN(0xC7891428, 0xCDC67EB6),
|
||||
TOBN(0x7FD02837, 0x0DF92B52), TOBN(0xB3353BBB, 0x64E0EC37),
|
||||
TOBN(0xECD06E15, 0x57CD0915), TOBN(0xB7D2BBD2, 0xDF016199),
|
||||
TOBN(0xC8484B1E, 0x052588B9), TOBN(0xDB2A3B73, 0x13D3FE14),
|
||||
TOBN(0xD052B985, 0xD182EA0A), TOBN(0xA4BD1BFF, 0xE83B9C80),
|
||||
TOBN(0xDFC967C1, 0xFB3F2E55), TOBN(0xB5045AF2, 0x767164E1),
|
||||
TOBN(0x1D14348F, 0x6F2F9193), TOBN(0x64E67982, 0x428EBC83),
|
||||
TOBN(0x8AC376D2, 0x82D6ED38), TOBN(0x777DE62A, 0xAAB8A862),
|
||||
TOBN(0xDDF463E5, 0xE9EC144B), TOBN(0x0196F931, 0xC77A57F2),
|
||||
TOBN(0xA55AE313, 0x41000A65), TOBN(0x901228F8, 0xC28CBB18),
|
||||
TOBN(0xBC3773BF, 0x7E8C6F62), TOBN(0xBE3A6C1B, 0x0C6B47B1),
|
||||
TOBN(0xFF4FED4A, 0xAC0BB555), TOBN(0x10DBC150, 0x77BE463F),
|
||||
TOBN(0x07F4793A, 0x1A0BA125), TOBN(0x4CA7B18F, 0x21EF2054),
|
||||
TOBN(0x2E775066, 0x60EDBD48), TOBN(0x3FB32C9B, 0x73134D0B),
|
||||
};
|
||||
static const BN_ULONG dh2048_256_q[] = {
|
||||
TOBN(0x64F5FBD3, 0xA308B0FE), TOBN(0x1EB3750B, 0x99B1A47D),
|
||||
TOBN(0x40129DA2, 0xB4479976), TOBN(0xA709A097, 0x8CF83642),
|
||||
TOBN(0xA308B0FE, 0x64F5FBD3), TOBN(0x99B1A47D, 0x1EB3750B),
|
||||
TOBN(0xB4479976, 0x40129DA2), TOBN(0x8CF83642, 0xA709A097),
|
||||
};
|
||||
|
||||
/* dh1024_safe_prime_1 is hard-coded in Apache httpd 2.2,
|
||||
* modules/ssl/ssl_engine_dh.c. */
|
||||
static const BN_ULONG dh1024_safe_prime_1[] = {
|
||||
TOBN(0x24218EB3, 0xE7393E0F), TOBN(0xE2BD68B0, 0x7DE0F4D6),
|
||||
TOBN(0x88AEAA74, 0x07DD62DB), TOBN(0x9DDD3305, 0x10EA9FCC),
|
||||
TOBN(0x74087D15, 0xA7DBCA78), TOBN(0x78045B07, 0xDAE88600),
|
||||
TOBN(0x1AAD3B72, 0x33168A46), TOBN(0x7BEDDCFD, 0xFF590137),
|
||||
TOBN(0x7A635E81, 0xFE324A46), TOBN(0x420B2A29, 0x5AC179BA),
|
||||
TOBN(0x177E16D5, 0x13B4B4D7), TOBN(0x639C72FB, 0x849F912E),
|
||||
TOBN(0x98BCE951, 0xB88174CB), TOBN(0xA45F520B, 0x0C84D239),
|
||||
TOBN(0x4AFD0AD5, 0x36D693D3), TOBN(0xCBBBDC19, 0xD67DE440),
|
||||
TOBN(0xE7393E0F, 0x24218EB3), TOBN(0x7DE0F4D6, 0xE2BD68B0),
|
||||
TOBN(0x07DD62DB, 0x88AEAA74), TOBN(0x10EA9FCC, 0x9DDD3305),
|
||||
TOBN(0xA7DBCA78, 0x74087D15), TOBN(0xDAE88600, 0x78045B07),
|
||||
TOBN(0x33168A46, 0x1AAD3B72), TOBN(0xFF590137, 0x7BEDDCFD),
|
||||
TOBN(0xFE324A46, 0x7A635E81), TOBN(0x5AC179BA, 0x420B2A29),
|
||||
TOBN(0x13B4B4D7, 0x177E16D5), TOBN(0x849F912E, 0x639C72FB),
|
||||
TOBN(0xB88174CB, 0x98BCE951), TOBN(0x0C84D239, 0xA45F520B),
|
||||
TOBN(0x36D693D3, 0x4AFD0AD5), TOBN(0xD67DE440, 0xCBBBDC19),
|
||||
};
|
||||
|
||||
/* dh1024_safe_prime_2 is hard-coded in nginx,
|
||||
* src/event/ngx_event_openssl.c. */
|
||||
static const BN_ULONG dh1024_safe_prime_2[] = {
|
||||
TOBN(0xCFE16B9B, 0x071DF045), TOBN(0x146757DA, 0x88D0F65D),
|
||||
TOBN(0x58FAFD49, 0x4A63AB1E), TOBN(0xEF9EA027, 0x35D8CECE),
|
||||
TOBN(0x70CC9A50, 0x25ECE662), TOBN(0x81DC2CA7, 0xF29BA5DF),
|
||||
TOBN(0xF7D36CC8, 0x8F68B076), TOBN(0xA757E304, 0x60E91A92),
|
||||
TOBN(0x9BE67780, 0x87A2BC04), TOBN(0xA5FDF1D2, 0xBEECA565),
|
||||
TOBN(0x922614C5, 0x5CCBBAA8), TOBN(0xE710800C, 0x6C030276),
|
||||
TOBN(0x0FB3504C, 0x08EED4EB), TOBN(0x68B42D4B, 0xD958A3F5),
|
||||
TOBN(0x80E9CFDB, 0x7C43FCF5), TOBN(0xD8467490, 0xBBBC2DCA),
|
||||
TOBN(0x071DF045, 0xCFE16B9B), TOBN(0x88D0F65D, 0x146757DA),
|
||||
TOBN(0x4A63AB1E, 0x58FAFD49), TOBN(0x35D8CECE, 0xEF9EA027),
|
||||
TOBN(0x25ECE662, 0x70CC9A50), TOBN(0xF29BA5DF, 0x81DC2CA7),
|
||||
TOBN(0x8F68B076, 0xF7D36CC8), TOBN(0x60E91A92, 0xA757E304),
|
||||
TOBN(0x87A2BC04, 0x9BE67780), TOBN(0xBEECA565, 0xA5FDF1D2),
|
||||
TOBN(0x5CCBBAA8, 0x922614C5), TOBN(0x6C030276, 0xE710800C),
|
||||
TOBN(0x08EED4EB, 0x0FB3504C), TOBN(0xD958A3F5, 0x68B42D4B),
|
||||
TOBN(0x7C43FCF5, 0x80E9CFDB), TOBN(0xBBBC2DCA, 0xD8467490),
|
||||
};
|
||||
|
||||
/* dh1024_safe_prime_3 is offered as a parameter by several high-traffic sites,
|
||||
* including mozilla.org, as of Jan 2015. */
|
||||
static const BN_ULONG dh1024_safe_prime_3[] = {
|
||||
TOBN(0x349E721B, 0x671746AE), TOBN(0xD75E93B2, 0x258A0655),
|
||||
TOBN(0x25592EB6, 0xD425E6FB), TOBN(0xBF7CDD9A, 0x0C46AB04),
|
||||
TOBN(0x28968680, 0x0AD0BC99), TOBN(0xD0B7EB49, 0xF53907FB),
|
||||
TOBN(0xEBC85C1D, 0x202EABB3), TOBN(0x364D8C71, 0x3129C693),
|
||||
TOBN(0x2D46F195, 0x53728351), TOBN(0x8C76CC85, 0xDF326DD6),
|
||||
TOBN(0x9188E24E, 0xF898B3F9), TOBN(0x2855DFD2, 0x95EFB13C),
|
||||
TOBN(0x7B2241FE, 0x1F5DAC48), TOBN(0x99A13D9F, 0x117B6BF7),
|
||||
TOBN(0x3A3468C7, 0x0F97CDDA), TOBN(0x74A8297B, 0xC9BBF5F7)};
|
||||
TOBN(0x671746AE, 0x349E721B), TOBN(0x258A0655, 0xD75E93B2),
|
||||
TOBN(0xD425E6FB, 0x25592EB6), TOBN(0x0C46AB04, 0xBF7CDD9A),
|
||||
TOBN(0x0AD0BC99, 0x28968680), TOBN(0xF53907FB, 0xD0B7EB49),
|
||||
TOBN(0x202EABB3, 0xEBC85C1D), TOBN(0x3129C693, 0x364D8C71),
|
||||
TOBN(0x53728351, 0x2D46F195), TOBN(0xDF326DD6, 0x8C76CC85),
|
||||
TOBN(0xF898B3F9, 0x9188E24E), TOBN(0x95EFB13C, 0x2855DFD2),
|
||||
TOBN(0x1F5DAC48, 0x7B2241FE), TOBN(0x117B6BF7, 0x99A13D9F),
|
||||
TOBN(0x0F97CDDA, 0x3A3468C7), TOBN(0xC9BBF5F7, 0x74A8297B)};
|
||||
|
||||
/* dh1024_safe_prime_4 is hard-coded in Apache httpd 2.0,
|
||||
* modules/ssl/ssl_engine_dh.c. */
|
||||
static const BN_ULONG dh1024_safe_prime_4[] = {
|
||||
TOBN(0x0DD5C86B, 0x5085E21F), TOBN(0xD823C650, 0x871538DF),
|
||||
TOBN(0x262E56A8, 0x125136F7), TOBN(0x839EB5DB, 0x974E9EF1),
|
||||
TOBN(0x1B13A63C, 0xEA9BAD99), TOBN(0x3D76E05E, 0x6044CF02),
|
||||
TOBN(0x1BAC9B5C, 0x611EBBBE), TOBN(0x4E5327DF, 0x3E371D79),
|
||||
TOBN(0x061CBC05, 0x000E6EDD), TOBN(0x20129B48, 0x2F971F3C),
|
||||
TOBN(0x3048D5A2, 0xA6EF09C4), TOBN(0xCBD523A6, 0xFA15A259),
|
||||
TOBN(0x4A79A770, 0x2A206490), TOBN(0x51BB055E, 0x91B78182),
|
||||
TOBN(0xBDD4798E, 0x7CF180C3), TOBN(0x495BE32C, 0xE6969D3D)};
|
||||
TOBN(0x5085E21F, 0x0DD5C86B), TOBN(0x871538DF, 0xD823C650),
|
||||
TOBN(0x125136F7, 0x262E56A8), TOBN(0x974E9EF1, 0x839EB5DB),
|
||||
TOBN(0xEA9BAD99, 0x1B13A63C), TOBN(0x6044CF02, 0x3D76E05E),
|
||||
TOBN(0x611EBBBE, 0x1BAC9B5C), TOBN(0x3E371D79, 0x4E5327DF),
|
||||
TOBN(0x000E6EDD, 0x061CBC05), TOBN(0x2F971F3C, 0x20129B48),
|
||||
TOBN(0xA6EF09C4, 0x3048D5A2), TOBN(0xFA15A259, 0xCBD523A6),
|
||||
TOBN(0x2A206490, 0x4A79A770), TOBN(0x91B78182, 0x51BB055E),
|
||||
TOBN(0x7CF180C3, 0xBDD4798E), TOBN(0xE6969D3D, 0x495BE32C)};
|
||||
|
||||
static const BN_ULONG bn_two_data[] = {2};
|
||||
|
||||
#define STATIC_BIGNUM(x) \
|
||||
{ \
|
||||
(BN_ULONG *) x, sizeof(x) / sizeof(BN_ULONG), \
|
||||
sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
|
||||
}
|
||||
|
||||
struct standard_parameters {
|
||||
BIGNUM p, q, g;
|
||||
};
|
||||
@@ -260,7 +247,7 @@ static const BIGNUM dh1024_safe_prime[] = {
|
||||
STATIC_BIGNUM(dh1024_safe_prime_4)
|
||||
};
|
||||
|
||||
BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
|
||||
static BIGNUM bn_two = STATIC_BIGNUM(bn_two_data);
|
||||
|
||||
static DH *get_standard_parameters(const struct standard_parameters *params,
|
||||
const ENGINE *engine) {
|
||||
|
||||
+153
-183
@@ -51,12 +51,12 @@
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define asm __asm__
|
||||
|
||||
/* This is a generic 32-bit "collector" for message digest algorithms. It
|
||||
* collects input character stream into chunks of 32-bit values and invokes the
|
||||
@@ -74,14 +74,15 @@ extern "C" {
|
||||
*
|
||||
* typedef struct <name>_state_st {
|
||||
* uint32_t h[<chaining length> / sizeof(uint32_t)];
|
||||
* uint32_t Nl,Nh;
|
||||
* uint32_t data[HASH_CBLOCK / sizeof(uint32_t)];
|
||||
* unsigned int num
|
||||
* uint32_t Nl, Nh;
|
||||
* uint8_t data[HASH_CBLOCK];
|
||||
* unsigned num;
|
||||
* ...
|
||||
* } <NAME>_CTX;
|
||||
*
|
||||
* <chaining length> is the output length of the hash in bytes, before
|
||||
* any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and SHA-512).
|
||||
* any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and
|
||||
* SHA-512).
|
||||
*
|
||||
* |HASH_UPDATE| must be defined as the name of the "Update" function to
|
||||
* generate.
|
||||
@@ -133,220 +134,189 @@ extern "C" {
|
||||
#error "HASH_BLOCK_DATA_ORDER must be defined!"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Engage compiler specific rotate intrinsic function if available.
|
||||
*/
|
||||
#undef ROTATE
|
||||
# if defined(_MSC_VER)
|
||||
# define ROTATE(a,n) _lrotl(a,n)
|
||||
# elif defined(__ICC)
|
||||
# define ROTATE(a,n) _rotl(a,n)
|
||||
# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
|
||||
/*
|
||||
* Some GNU C inline assembler templates. Note that these are
|
||||
* rotates by *constant* number of bits! But that's exactly
|
||||
* what we need here...
|
||||
* <appro@fy.chalmers.se>
|
||||
*/
|
||||
# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
# define ROTATE(a,n) ({ register uint32_t ret; \
|
||||
asm ( \
|
||||
"roll %1,%0" \
|
||||
: "=r"(ret) \
|
||||
: "I"(n), "0"((uint32_t)(a)) \
|
||||
: "cc"); \
|
||||
ret; \
|
||||
})
|
||||
# endif /* OPENSSL_X86 || OPENSSL_X86_64 */
|
||||
# endif /* COMPILER */
|
||||
|
||||
#ifndef ROTATE
|
||||
#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
|
||||
#ifndef HASH_MAKE_STRING
|
||||
#error "HASH_MAKE_STRING must be defined!"
|
||||
#endif
|
||||
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
|
||||
#ifndef PEDANTIC
|
||||
# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM)
|
||||
# if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
/*
|
||||
* This gives ~30-40% performance improvement in SHA-256 compiled
|
||||
* with gcc [on P4]. Well, first macro to be frank. We can pull
|
||||
* this trick on x86* platforms only, because these CPUs can fetch
|
||||
* unaligned data without raising an exception.
|
||||
*/
|
||||
# define HOST_c2l(c,l) ({ uint32_t r=*((const uint32_t *)(c)); \
|
||||
asm ("bswapl %0":"=r"(r):"0"(r)); \
|
||||
(c)+=4; (l)=r; })
|
||||
# define HOST_l2c(l,c) ({ uint32_t r=(l); \
|
||||
asm ("bswapl %0":"=r"(r):"0"(r)); \
|
||||
*((uint32_t *)(c))=r; (c)+=4; r; })
|
||||
# elif defined(__aarch64__)
|
||||
# if defined(__BYTE_ORDER__)
|
||||
# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
|
||||
# define HOST_c2l(c,l) ({ uint32_t r; \
|
||||
asm ("rev %w0,%w1" \
|
||||
:"=r"(r) \
|
||||
:"r"(*((const uint32_t *)(c))));\
|
||||
(c)+=4; (l)=r; })
|
||||
# define HOST_l2c(l,c) ({ uint32_t r; \
|
||||
asm ("rev %w0,%w1" \
|
||||
:"=r"(r) \
|
||||
:"r"((uint32_t)(l))); \
|
||||
*((uint32_t *)(c))=r; (c)+=4; r; })
|
||||
# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
|
||||
# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4)
|
||||
# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, (l))
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(PEDANTIC) && defined(__GNUC__) && __GNUC__ >= 2 && \
|
||||
!defined(OPENSSL_NO_ASM)
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
/* The first macro gives a ~30-40% performance improvement in SHA-256 compiled
|
||||
* with gcc on P4. This can only be done on x86, where unaligned data fetches
|
||||
* are possible. */
|
||||
#define HOST_c2l(c, l) \
|
||||
(void)({ \
|
||||
uint32_t r = *((const uint32_t *)(c)); \
|
||||
__asm__("bswapl %0" : "=r"(r) : "0"(r)); \
|
||||
(c) += 4; \
|
||||
(l) = r; \
|
||||
})
|
||||
#define HOST_l2c(l, c) \
|
||||
(void)({ \
|
||||
uint32_t r = (l); \
|
||||
__asm__("bswapl %0" : "=r"(r) : "0"(r)); \
|
||||
*((uint32_t *)(c)) = r; \
|
||||
(c) += 4; \
|
||||
r; \
|
||||
})
|
||||
#elif defined(__aarch64__) && defined(__BYTE_ORDER__)
|
||||
#if defined(__ORDER_LITTLE_ENDIAN__) && \
|
||||
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define HOST_c2l(c, l) \
|
||||
(void)({ \
|
||||
uint32_t r; \
|
||||
__asm__("rev %w0, %w1" : "=r"(r) : "r"(*((const uint32_t *)(c)))); \
|
||||
(c) += 4; \
|
||||
(l) = r; \
|
||||
})
|
||||
#define HOST_l2c(l, c) \
|
||||
(void)({ \
|
||||
uint32_t r; \
|
||||
__asm__("rev %w0, %w1" : "=r"(r) : "r"((uint32_t)(l))); \
|
||||
*((uint32_t *)(c)) = r; \
|
||||
(c) += 4; \
|
||||
r; \
|
||||
})
|
||||
#elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
|
||||
#define HOST_l2c(l, c) (*((uint32_t *)(c)) = (l), (c) += 4, (l))
|
||||
#endif /* __aarch64__ && __BYTE_ORDER__ */
|
||||
#endif /* ARCH */
|
||||
#endif /* !PEDANTIC && GNUC && !NO_ASM */
|
||||
|
||||
#ifndef HOST_c2l
|
||||
#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++)))<<24), \
|
||||
l|=(((uint32_t)(*((c)++)))<<16), \
|
||||
l|=(((uint32_t)(*((c)++)))<< 8), \
|
||||
l|=(((uint32_t)(*((c)++))) ))
|
||||
#define HOST_c2l(c, l) \
|
||||
(void)(l = (((uint32_t)(*((c)++))) << 24), \
|
||||
l |= (((uint32_t)(*((c)++))) << 16), \
|
||||
l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++)))))
|
||||
#endif
|
||||
|
||||
#ifndef HOST_l2c
|
||||
#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l)>>24)&0xff), \
|
||||
*((c)++)=(uint8_t)(((l)>>16)&0xff), \
|
||||
*((c)++)=(uint8_t)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(uint8_t)(((l) )&0xff), \
|
||||
l)
|
||||
#define HOST_l2c(l, c) \
|
||||
(void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l)) & 0xff))
|
||||
#endif
|
||||
|
||||
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
|
||||
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
|
||||
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
|
||||
# define HOST_c2l(c,l) (void)((l)=*((const uint32_t *)(c)), (c)+=4)
|
||||
# define HOST_l2c(l,c) (*((uint32_t *)(c))=(l), (c)+=4, l)
|
||||
#endif
|
||||
/* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
|
||||
#define HOST_c2l(c, l) (void)((l) = *((const uint32_t *)(c)), (c) += 4)
|
||||
#define HOST_l2c(l, c) (void)(*((uint32_t *)(c)) = (l), (c) += 4, l)
|
||||
#endif /* OPENSSL_X86 || OPENSSL_X86_64 */
|
||||
|
||||
#ifndef HOST_c2l
|
||||
#define HOST_c2l(c,l) (void)(l =(((uint32_t)(*((c)++))) ), \
|
||||
l|=(((uint32_t)(*((c)++)))<< 8), \
|
||||
l|=(((uint32_t)(*((c)++)))<<16), \
|
||||
l|=(((uint32_t)(*((c)++)))<<24))
|
||||
#define HOST_c2l(c, l) \
|
||||
(void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \
|
||||
l |= (((uint32_t)(*((c)++))) << 16), \
|
||||
l |= (((uint32_t)(*((c)++))) << 24))
|
||||
#endif
|
||||
|
||||
#ifndef HOST_l2c
|
||||
#define HOST_l2c(l,c) (*((c)++)=(uint8_t)(((l) )&0xff), \
|
||||
*((c)++)=(uint8_t)(((l)>> 8)&0xff), \
|
||||
*((c)++)=(uint8_t)(((l)>>16)&0xff), \
|
||||
*((c)++)=(uint8_t)(((l)>>24)&0xff), \
|
||||
l)
|
||||
#define HOST_l2c(l, c) \
|
||||
(void)(*((c)++) = (uint8_t)(((l)) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
|
||||
*((c)++) = (uint8_t)(((l) >> 24) & 0xff))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* DATA_ORDER */
|
||||
|
||||
int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
|
||||
{
|
||||
const uint8_t *data=data_;
|
||||
uint8_t *p;
|
||||
uint32_t l;
|
||||
size_t n;
|
||||
int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) {
|
||||
const uint8_t *data = data_;
|
||||
|
||||
if (len==0) return 1;
|
||||
if (len == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
l=(c->Nl+(((uint32_t)len)<<3))&0xffffffffUL;
|
||||
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
|
||||
* Wei Dai <weidai@eskimo.com> for pointing it out. */
|
||||
if (l < c->Nl) /* overflow */
|
||||
c->Nh++;
|
||||
c->Nh+=(uint32_t)(len>>29); /* might cause compiler warning on 16-bit */
|
||||
c->Nl=l;
|
||||
uint32_t l = c->Nl + (((uint32_t)len) << 3);
|
||||
if (l < c->Nl) {
|
||||
/* Handle carries. */
|
||||
c->Nh++;
|
||||
}
|
||||
c->Nh += (uint32_t)(len >> 29);
|
||||
c->Nl = l;
|
||||
|
||||
n = c->num;
|
||||
if (n != 0)
|
||||
{
|
||||
p=(uint8_t *)c->data;
|
||||
size_t n = c->num;
|
||||
if (n != 0) {
|
||||
if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
|
||||
memcpy(c->data + n, data, HASH_CBLOCK - n);
|
||||
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
|
||||
n = HASH_CBLOCK - n;
|
||||
data += n;
|
||||
len -= n;
|
||||
c->num = 0;
|
||||
/* Keep |c->data| zeroed when unused. */
|
||||
memset(c->data, 0, HASH_CBLOCK);
|
||||
} else {
|
||||
memcpy(c->data + n, data, len);
|
||||
c->num += (unsigned)len;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
|
||||
{
|
||||
memcpy (p+n,data,HASH_CBLOCK-n);
|
||||
HASH_BLOCK_DATA_ORDER (c->h,p,1);
|
||||
n = HASH_CBLOCK-n;
|
||||
data += n;
|
||||
len -= n;
|
||||
c->num = 0;
|
||||
memset (p,0,HASH_CBLOCK); /* keep it zeroed */
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (p+n,data,len);
|
||||
c->num += (unsigned int)len;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
n = len / HASH_CBLOCK;
|
||||
if (n > 0) {
|
||||
HASH_BLOCK_DATA_ORDER(c->h, data, n);
|
||||
n *= HASH_CBLOCK;
|
||||
data += n;
|
||||
len -= n;
|
||||
}
|
||||
|
||||
n = len/HASH_CBLOCK;
|
||||
if (n > 0)
|
||||
{
|
||||
HASH_BLOCK_DATA_ORDER (c->h,data,n);
|
||||
n *= HASH_CBLOCK;
|
||||
data += n;
|
||||
len -= n;
|
||||
}
|
||||
|
||||
if (len != 0)
|
||||
{
|
||||
p = (uint8_t *)c->data;
|
||||
c->num = (unsigned int)len;
|
||||
memcpy (p,data,len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (len != 0) {
|
||||
c->num = (unsigned)len;
|
||||
memcpy(c->data, data, len);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void HASH_TRANSFORM (HASH_CTX *c, const uint8_t *data)
|
||||
{
|
||||
HASH_BLOCK_DATA_ORDER (c->h,data,1);
|
||||
}
|
||||
void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) {
|
||||
HASH_BLOCK_DATA_ORDER(c->h, data, 1);
|
||||
}
|
||||
|
||||
|
||||
int HASH_FINAL (uint8_t *md, HASH_CTX *c)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)c->data;
|
||||
size_t n = c->num;
|
||||
int HASH_FINAL(uint8_t *md, HASH_CTX *c) {
|
||||
/* |c->data| always has room for at least one byte. A full block would have
|
||||
* been consumed. */
|
||||
size_t n = c->num;
|
||||
assert(n < HASH_CBLOCK);
|
||||
c->data[n] = 0x80;
|
||||
n++;
|
||||
|
||||
p[n] = 0x80; /* there is always room for one */
|
||||
n++;
|
||||
/* Fill the block with zeros if there isn't room for a 64-bit length. */
|
||||
if (n > (HASH_CBLOCK - 8)) {
|
||||
memset(c->data + n, 0, HASH_CBLOCK - n);
|
||||
n = 0;
|
||||
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
|
||||
}
|
||||
memset(c->data + n, 0, HASH_CBLOCK - 8 - n);
|
||||
|
||||
if (n > (HASH_CBLOCK-8))
|
||||
{
|
||||
memset (p+n,0,HASH_CBLOCK-n);
|
||||
n=0;
|
||||
HASH_BLOCK_DATA_ORDER (c->h,p,1);
|
||||
}
|
||||
memset (p+n,0,HASH_CBLOCK-8-n);
|
||||
|
||||
p += HASH_CBLOCK-8;
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
(void)HOST_l2c(c->Nh,p);
|
||||
(void)HOST_l2c(c->Nl,p);
|
||||
/* Append a 64-bit length to the block and process it. */
|
||||
uint8_t *p = c->data + HASH_CBLOCK - 8;
|
||||
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
|
||||
HOST_l2c(c->Nh, p);
|
||||
HOST_l2c(c->Nl, p);
|
||||
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
|
||||
(void)HOST_l2c(c->Nl,p);
|
||||
(void)HOST_l2c(c->Nh,p);
|
||||
HOST_l2c(c->Nl, p);
|
||||
HOST_l2c(c->Nh, p);
|
||||
#endif
|
||||
p -= HASH_CBLOCK;
|
||||
HASH_BLOCK_DATA_ORDER (c->h,p,1);
|
||||
c->num=0;
|
||||
memset (p,0,HASH_CBLOCK);
|
||||
assert(p == c->data + HASH_CBLOCK);
|
||||
HASH_BLOCK_DATA_ORDER(c->h, c->data, 1);
|
||||
c->num = 0;
|
||||
memset(c->data, 0, HASH_CBLOCK);
|
||||
|
||||
#ifndef HASH_MAKE_STRING
|
||||
#error "HASH_MAKE_STRING must be defined!"
|
||||
#else
|
||||
HASH_MAKE_STRING(c,md);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
HASH_MAKE_STRING(c, md);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif /* OPENSSL_HEADER_MD32_COMMON_H */
|
||||
#endif /* OPENSSL_HEADER_MD32_COMMON_H */
|
||||
|
||||
+9
-14
@@ -98,12 +98,7 @@ DSA *DSA_new(void) {
|
||||
dsa->references = 1;
|
||||
|
||||
CRYPTO_MUTEX_init(&dsa->method_mont_p_lock);
|
||||
|
||||
if (!CRYPTO_new_ex_data(&g_ex_data_class, dsa, &dsa->ex_data)) {
|
||||
CRYPTO_MUTEX_cleanup(&dsa->method_mont_p_lock);
|
||||
OPENSSL_free(dsa);
|
||||
return NULL;
|
||||
}
|
||||
CRYPTO_new_ex_data(&dsa->ex_data);
|
||||
|
||||
return dsa;
|
||||
}
|
||||
@@ -541,10 +536,6 @@ redo:
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = DSA_SIG_new();
|
||||
if (ret == NULL) {
|
||||
goto err;
|
||||
}
|
||||
/* Redo if r or s is zero as required by FIPS 186-3: this is
|
||||
* very unlikely. */
|
||||
if (BN_is_zero(r) || BN_is_zero(s)) {
|
||||
@@ -554,11 +545,15 @@ redo:
|
||||
}
|
||||
goto redo;
|
||||
}
|
||||
ret = DSA_SIG_new();
|
||||
if (ret == NULL) {
|
||||
goto err;
|
||||
}
|
||||
ret->r = r;
|
||||
ret->s = s;
|
||||
|
||||
err:
|
||||
if (!ret) {
|
||||
if (ret == NULL) {
|
||||
OPENSSL_PUT_ERROR(DSA, reason);
|
||||
BN_free(r);
|
||||
BN_free(s);
|
||||
@@ -864,11 +859,11 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
|
||||
int index;
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
|
||||
dup_func, free_func)) {
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
|
||||
free_func)) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
|
||||
@@ -67,10 +67,6 @@ $code.=<<___;
|
||||
.Lpoly:
|
||||
.quad 0xffffffffffffffff, 0x00000000ffffffff, 0x0000000000000000, 0xffffffff00000001
|
||||
|
||||
# 2^512 mod P precomputed for NIST P256 polynomial
|
||||
.LRR:
|
||||
.quad 0x0000000000000003, 0xfffffffbffffffff, 0xfffffffffffffffe, 0x00000004fffffffd
|
||||
|
||||
.LOne:
|
||||
.long 1,1,1,1,1,1,1,1
|
||||
.LTwo:
|
||||
@@ -91,7 +87,6 @@ my ($r_ptr,$a_ptr,$b_ptr)=("%rdi","%rsi","%rdx");
|
||||
|
||||
$code.=<<___;
|
||||
|
||||
.globl ecp_nistz256_mul_by_2
|
||||
.type ecp_nistz256_mul_by_2,\@function,2
|
||||
.align 64
|
||||
ecp_nistz256_mul_by_2:
|
||||
@@ -133,224 +128,6 @@ ecp_nistz256_mul_by_2:
|
||||
ret
|
||||
.size ecp_nistz256_mul_by_2,.-ecp_nistz256_mul_by_2
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_div_by_2(uint64_t res[4], uint64_t a[4]);
|
||||
.globl ecp_nistz256_div_by_2
|
||||
.type ecp_nistz256_div_by_2,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_div_by_2:
|
||||
push %r12
|
||||
push %r13
|
||||
|
||||
mov 8*0($a_ptr), $a0
|
||||
mov 8*1($a_ptr), $a1
|
||||
mov 8*2($a_ptr), $a2
|
||||
mov $a0, $t0
|
||||
mov 8*3($a_ptr), $a3
|
||||
lea .Lpoly(%rip), $a_ptr
|
||||
|
||||
mov $a1, $t1
|
||||
xor $t4, $t4
|
||||
add 8*0($a_ptr), $a0
|
||||
mov $a2, $t2
|
||||
adc 8*1($a_ptr), $a1
|
||||
adc 8*2($a_ptr), $a2
|
||||
mov $a3, $t3
|
||||
adc 8*3($a_ptr), $a3
|
||||
adc \$0, $t4
|
||||
xor $a_ptr, $a_ptr # borrow $a_ptr
|
||||
test \$1, $t0
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
cmovz $t2, $a2
|
||||
cmovz $t3, $a3
|
||||
cmovz $a_ptr, $t4
|
||||
|
||||
mov $a1, $t0 # a0:a3>>1
|
||||
shr \$1, $a0
|
||||
shl \$63, $t0
|
||||
mov $a2, $t1
|
||||
shr \$1, $a1
|
||||
or $t0, $a0
|
||||
shl \$63, $t1
|
||||
mov $a3, $t2
|
||||
shr \$1, $a2
|
||||
or $t1, $a1
|
||||
shl \$63, $t2
|
||||
shr \$1, $a3
|
||||
shl \$63, $t4
|
||||
or $t2, $a2
|
||||
or $t4, $a3
|
||||
|
||||
mov $a0, 8*0($r_ptr)
|
||||
mov $a1, 8*1($r_ptr)
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
pop %r13
|
||||
pop %r12
|
||||
ret
|
||||
.size ecp_nistz256_div_by_2,.-ecp_nistz256_div_by_2
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_mul_by_3(uint64_t res[4], uint64_t a[4]);
|
||||
.globl ecp_nistz256_mul_by_3
|
||||
.type ecp_nistz256_mul_by_3,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_mul_by_3:
|
||||
push %r12
|
||||
push %r13
|
||||
|
||||
mov 8*0($a_ptr), $a0
|
||||
xor $t4, $t4
|
||||
mov 8*1($a_ptr), $a1
|
||||
add $a0, $a0 # a0:a3+a0:a3
|
||||
mov 8*2($a_ptr), $a2
|
||||
adc $a1, $a1
|
||||
mov 8*3($a_ptr), $a3
|
||||
mov $a0, $t0
|
||||
adc $a2, $a2
|
||||
adc $a3, $a3
|
||||
mov $a1, $t1
|
||||
adc \$0, $t4
|
||||
|
||||
sub \$-1, $a0
|
||||
mov $a2, $t2
|
||||
sbb .Lpoly+8*1(%rip), $a1
|
||||
sbb \$0, $a2
|
||||
mov $a3, $t3
|
||||
sbb .Lpoly+8*3(%rip), $a3
|
||||
test $t4, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
cmovz $t2, $a2
|
||||
cmovz $t3, $a3
|
||||
|
||||
xor $t4, $t4
|
||||
add 8*0($a_ptr), $a0 # a0:a3+=a_ptr[0:3]
|
||||
adc 8*1($a_ptr), $a1
|
||||
mov $a0, $t0
|
||||
adc 8*2($a_ptr), $a2
|
||||
adc 8*3($a_ptr), $a3
|
||||
mov $a1, $t1
|
||||
adc \$0, $t4
|
||||
|
||||
sub \$-1, $a0
|
||||
mov $a2, $t2
|
||||
sbb .Lpoly+8*1(%rip), $a1
|
||||
sbb \$0, $a2
|
||||
mov $a3, $t3
|
||||
sbb .Lpoly+8*3(%rip), $a3
|
||||
test $t4, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovz $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovz $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
pop %r13
|
||||
pop %r12
|
||||
ret
|
||||
.size ecp_nistz256_mul_by_3,.-ecp_nistz256_mul_by_3
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_add(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
|
||||
.globl ecp_nistz256_add
|
||||
.type ecp_nistz256_add,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_add:
|
||||
push %r12
|
||||
push %r13
|
||||
|
||||
mov 8*0($a_ptr), $a0
|
||||
xor $t4, $t4
|
||||
mov 8*1($a_ptr), $a1
|
||||
mov 8*2($a_ptr), $a2
|
||||
mov 8*3($a_ptr), $a3
|
||||
lea .Lpoly(%rip), $a_ptr
|
||||
|
||||
add 8*0($b_ptr), $a0
|
||||
adc 8*1($b_ptr), $a1
|
||||
mov $a0, $t0
|
||||
adc 8*2($b_ptr), $a2
|
||||
adc 8*3($b_ptr), $a3
|
||||
mov $a1, $t1
|
||||
adc \$0, $t4
|
||||
|
||||
sub 8*0($a_ptr), $a0
|
||||
mov $a2, $t2
|
||||
sbb 8*1($a_ptr), $a1
|
||||
sbb 8*2($a_ptr), $a2
|
||||
mov $a3, $t3
|
||||
sbb 8*3($a_ptr), $a3
|
||||
test $t4, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovz $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovz $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
pop %r13
|
||||
pop %r12
|
||||
ret
|
||||
.size ecp_nistz256_add,.-ecp_nistz256_add
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_sub(uint64_t res[4], uint64_t a[4], uint64_t b[4]);
|
||||
.globl ecp_nistz256_sub
|
||||
.type ecp_nistz256_sub,\@function,3
|
||||
.align 32
|
||||
ecp_nistz256_sub:
|
||||
push %r12
|
||||
push %r13
|
||||
|
||||
mov 8*0($a_ptr), $a0
|
||||
xor $t4, $t4
|
||||
mov 8*1($a_ptr), $a1
|
||||
mov 8*2($a_ptr), $a2
|
||||
mov 8*3($a_ptr), $a3
|
||||
lea .Lpoly(%rip), $a_ptr
|
||||
|
||||
sub 8*0($b_ptr), $a0
|
||||
sbb 8*1($b_ptr), $a1
|
||||
mov $a0, $t0
|
||||
sbb 8*2($b_ptr), $a2
|
||||
sbb 8*3($b_ptr), $a3
|
||||
mov $a1, $t1
|
||||
sbb \$0, $t4
|
||||
|
||||
add 8*0($a_ptr), $a0
|
||||
mov $a2, $t2
|
||||
adc 8*1($a_ptr), $a1
|
||||
adc 8*2($a_ptr), $a2
|
||||
mov $a3, $t3
|
||||
adc 8*3($a_ptr), $a3
|
||||
test $t4, $t4
|
||||
|
||||
cmovz $t0, $a0
|
||||
cmovz $t1, $a1
|
||||
mov $a0, 8*0($r_ptr)
|
||||
cmovz $t2, $a2
|
||||
mov $a1, 8*1($r_ptr)
|
||||
cmovz $t3, $a3
|
||||
mov $a2, 8*2($r_ptr)
|
||||
mov $a3, 8*3($r_ptr)
|
||||
|
||||
pop %r13
|
||||
pop %r12
|
||||
ret
|
||||
.size ecp_nistz256_sub,.-ecp_nistz256_sub
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_neg(uint64_t res[4], uint64_t a[4]);
|
||||
.globl ecp_nistz256_neg
|
||||
@@ -405,24 +182,6 @@ my ($t0,$t1,$t2,$t3,$t4)=("%rcx","%rbp","%rbx","%rdx","%rax");
|
||||
my ($poly1,$poly3)=($acc6,$acc7);
|
||||
|
||||
$code.=<<___;
|
||||
################################################################################
|
||||
# void ecp_nistz256_to_mont(
|
||||
# uint64_t res[4],
|
||||
# uint64_t in[4]);
|
||||
.globl ecp_nistz256_to_mont
|
||||
.type ecp_nistz256_to_mont,\@function,2
|
||||
.align 32
|
||||
ecp_nistz256_to_mont:
|
||||
___
|
||||
$code.=<<___ if ($addx);
|
||||
mov \$0x80100, %ecx
|
||||
and OPENSSL_ia32cap_P+8(%rip), %ecx
|
||||
___
|
||||
$code.=<<___;
|
||||
lea .LRR(%rip), $b_org
|
||||
jmp .Lmul_mont
|
||||
.size ecp_nistz256_to_mont,.-ecp_nistz256_to_mont
|
||||
|
||||
################################################################################
|
||||
# void ecp_nistz256_mul_mont(
|
||||
# uint64_t res[4],
|
||||
|
||||
+19
-50
@@ -525,8 +525,6 @@ void EC_GROUP_free(EC_GROUP *group) {
|
||||
group->meth->group_finish(group);
|
||||
}
|
||||
|
||||
ec_pre_comp_free(group->pre_comp);
|
||||
|
||||
EC_POINT_free(group->generator);
|
||||
BN_free(&group->order);
|
||||
BN_free(&group->cofactor);
|
||||
@@ -547,8 +545,6 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ec_pre_comp_free(dest->pre_comp);
|
||||
dest->pre_comp = ec_pre_comp_dup(src->pre_comp);
|
||||
dest->mont_data = src->mont_data;
|
||||
|
||||
if (src->generator != NULL) {
|
||||
@@ -617,12 +613,16 @@ const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) {
|
||||
return group->generator;
|
||||
}
|
||||
|
||||
const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) {
|
||||
assert(!BN_is_zero(&group->order));
|
||||
return &group->order;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) {
|
||||
if (!BN_copy(order, &group->order)) {
|
||||
if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return !BN_is_zero(order);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
|
||||
@@ -645,21 +645,6 @@ unsigned EC_GROUP_get_degree(const EC_GROUP *group) {
|
||||
return ec_GFp_simple_group_get_degree(group);
|
||||
}
|
||||
|
||||
int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
|
||||
if (group->meth->precompute_mult != NULL) {
|
||||
return group->meth->precompute_mult(group, ctx);
|
||||
}
|
||||
|
||||
return 1; /* nothing to do, so report success */
|
||||
}
|
||||
|
||||
int EC_GROUP_have_precompute_mult(const EC_GROUP *group) {
|
||||
if (group->pre_comp != NULL) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EC_POINT *EC_POINT_new(const EC_GROUP *group) {
|
||||
EC_POINT *ret;
|
||||
|
||||
@@ -856,39 +841,23 @@ int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
|
||||
}
|
||||
|
||||
int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) {
|
||||
/* just a convenient interface to EC_POINTs_mul() */
|
||||
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
|
||||
/* Previously, this function set |r| to the point at infinity if there was
|
||||
* nothing to multiply. But, nobody should be calling this function with
|
||||
* nothing to multiply in the first place. */
|
||||
if ((g_scalar == NULL && p_scalar == NULL) ||
|
||||
((p == NULL) != (p_scalar == NULL))) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const EC_POINT *points[1];
|
||||
const BIGNUM *scalars[1];
|
||||
|
||||
points[0] = point;
|
||||
scalars[0] = p_scalar;
|
||||
|
||||
return EC_POINTs_mul(group, r, g_scalar, (point != NULL && p_scalar != NULL),
|
||||
points, scalars, ctx);
|
||||
}
|
||||
|
||||
int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *ctx) {
|
||||
if (group->meth != r->meth) {
|
||||
if (group->meth != r->meth ||
|
||||
(p != NULL && group->meth != p->meth)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (points[i]->meth != r->meth) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != num) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
|
||||
return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx);
|
||||
}
|
||||
|
||||
int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
|
||||
|
||||
@@ -329,6 +329,11 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **inp, long len) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(ret->group)) >= 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
EC_POINT_free(ret->pub_key);
|
||||
ret->pub_key = EC_POINT_new(ret->group);
|
||||
if (ret->pub_key == NULL) {
|
||||
|
||||
+37
-58
@@ -104,24 +104,18 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
|
||||
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
ret->references = 1;
|
||||
|
||||
if (!CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data)) {
|
||||
goto err1;
|
||||
}
|
||||
CRYPTO_new_ex_data(&ret->ex_data);
|
||||
|
||||
if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) {
|
||||
goto err2;
|
||||
CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
|
||||
if (ret->ecdsa_meth) {
|
||||
METHOD_unref(ret->ecdsa_meth);
|
||||
}
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err2:
|
||||
CRYPTO_free_ex_data(&g_ex_data_class, ret, &ret->ex_data);
|
||||
err1:
|
||||
if (ret->ecdsa_meth) {
|
||||
METHOD_unref(ret->ecdsa_meth);
|
||||
}
|
||||
OPENSSL_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_KEY *EC_KEY_new_by_curve_name(int nid) {
|
||||
@@ -249,7 +243,15 @@ int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) {
|
||||
/* TODO(fork): duplicating the group seems wasteful but see
|
||||
* |EC_KEY_set_conv_form|. */
|
||||
key->group = EC_GROUP_dup(group);
|
||||
return (key->group == NULL) ? 0 : 1;
|
||||
if (key->group == NULL) {
|
||||
return 0;
|
||||
}
|
||||
/* XXX: |BN_cmp| is not constant time. */
|
||||
if (key->priv_key != NULL &&
|
||||
BN_cmp(key->priv_key, EC_GROUP_get0_order(group)) >= 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
|
||||
@@ -257,6 +259,12 @@ const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) {
|
||||
}
|
||||
|
||||
int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) {
|
||||
/* XXX: |BN_cmp| is not constant time. */
|
||||
if (key->group != NULL &&
|
||||
BN_cmp(priv_key, EC_GROUP_get0_order(key->group)) >= 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
|
||||
return 0;
|
||||
}
|
||||
BN_clear_free(key->priv_key);
|
||||
key->priv_key = BN_dup(priv_key);
|
||||
return (key->priv_key == NULL) ? 0 : 1;
|
||||
@@ -286,17 +294,9 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) {
|
||||
key->conv_form = cform;
|
||||
}
|
||||
|
||||
int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) {
|
||||
if (key->group == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return EC_GROUP_precompute_mult(key->group, ctx);
|
||||
}
|
||||
|
||||
int EC_KEY_check_key(const EC_KEY *eckey) {
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (!eckey || !eckey->group || !eckey->pub_key) {
|
||||
@@ -310,10 +310,8 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
|
||||
}
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
point = EC_POINT_new(eckey->group);
|
||||
|
||||
if (ctx == NULL ||
|
||||
point == NULL) {
|
||||
if (ctx == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -322,19 +320,11 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
/* testing whether pub_key * order is the point at infinity */
|
||||
/* TODO(fork): can this be skipped if the cofactor is one or if we're about
|
||||
* to check the private key, below? */
|
||||
order = &eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
if (eckey->group->meth->check_pub_key_order != NULL &&
|
||||
!eckey->group->meth->check_pub_key_order(eckey->group, eckey->pub_key,
|
||||
ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
@@ -342,11 +332,14 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
|
||||
* check if generator * priv_key == pub_key
|
||||
*/
|
||||
if (eckey->priv_key) {
|
||||
if (BN_cmp(eckey->priv_key, order) >= 0) {
|
||||
/* XXX: |BN_cmp| is not constant time. */
|
||||
if (BN_cmp(eckey->priv_key, EC_GROUP_get0_order(eckey->group)) >= 0) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
|
||||
point = EC_POINT_new(eckey->group);
|
||||
if (point == NULL ||
|
||||
!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
@@ -415,8 +408,7 @@ err:
|
||||
|
||||
int EC_KEY_generate_key(EC_KEY *eckey) {
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL, *order = NULL;
|
||||
BIGNUM *priv_key = NULL;
|
||||
EC_POINT *pub_key = NULL;
|
||||
|
||||
if (!eckey || !eckey->group) {
|
||||
@@ -424,14 +416,6 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
order = BN_new();
|
||||
ctx = BN_CTX_new();
|
||||
|
||||
if (order == NULL ||
|
||||
ctx == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (eckey->priv_key == NULL) {
|
||||
priv_key = BN_new();
|
||||
if (priv_key == NULL) {
|
||||
@@ -441,10 +425,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
|
||||
priv_key = eckey->priv_key;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order(eckey->group, order, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
const BIGNUM *order = EC_GROUP_get0_order(eckey->group);
|
||||
do {
|
||||
if (!BN_rand_range(priv_key, order)) {
|
||||
goto err;
|
||||
@@ -460,7 +441,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
|
||||
pub_key = eckey->pub_key;
|
||||
}
|
||||
|
||||
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) {
|
||||
if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -470,23 +451,21 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
BN_free(order);
|
||||
if (eckey->pub_key == NULL) {
|
||||
EC_POINT_free(pub_key);
|
||||
}
|
||||
if (eckey->priv_key == NULL) {
|
||||
BN_free(priv_key);
|
||||
}
|
||||
BN_CTX_free(ctx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_func,
|
||||
CRYPTO_EX_free *free_func) {
|
||||
int index;
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
|
||||
dup_func, free_func)) {
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
|
||||
free_func)) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
|
||||
+40
-18
@@ -74,24 +74,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
const EC_METHOD *EC_GFp_mont_method(void) {
|
||||
static const EC_METHOD ret = {ec_GFp_mont_group_init,
|
||||
ec_GFp_mont_group_finish,
|
||||
ec_GFp_mont_group_clear_finish,
|
||||
ec_GFp_mont_group_copy,
|
||||
ec_GFp_mont_group_set_curve,
|
||||
ec_GFp_simple_point_get_affine_coordinates,
|
||||
ec_wNAF_mul /* XXX: Not constant time. */,
|
||||
ec_wNAF_precompute_mult,
|
||||
ec_GFp_mont_field_mul,
|
||||
ec_GFp_mont_field_sqr,
|
||||
ec_GFp_mont_field_encode,
|
||||
ec_GFp_mont_field_decode,
|
||||
ec_GFp_mont_field_set_to_one};
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
int ec_GFp_mont_group_init(EC_GROUP *group) {
|
||||
int ok;
|
||||
|
||||
@@ -256,3 +238,43 @@ int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ec_GFp_mont_check_pub_key_order(const EC_GROUP *group,
|
||||
const EC_POINT* pub_key,
|
||||
BN_CTX *ctx) {
|
||||
EC_POINT *point = EC_POINT_new(group);
|
||||
int ret = 0;
|
||||
|
||||
if (point == NULL ||
|
||||
!ec_wNAF_mul(group, point, NULL, pub_key, EC_GROUP_get0_order(group),
|
||||
ctx) ||
|
||||
!EC_POINT_is_at_infinity(group, point)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const EC_METHOD *EC_GFp_mont_method(void) {
|
||||
static const EC_METHOD ret = {
|
||||
ec_GFp_mont_group_init,
|
||||
ec_GFp_mont_group_finish,
|
||||
ec_GFp_mont_group_clear_finish,
|
||||
ec_GFp_mont_group_copy,
|
||||
ec_GFp_mont_group_set_curve,
|
||||
ec_GFp_simple_point_get_affine_coordinates,
|
||||
ec_wNAF_mul /* XXX: Not constant time. */,
|
||||
ec_GFp_mont_check_pub_key_order,
|
||||
ec_GFp_mont_field_mul,
|
||||
ec_GFp_mont_field_sqr,
|
||||
ec_GFp_mont_field_encode,
|
||||
ec_GFp_mont_field_decode,
|
||||
ec_GFp_mont_field_set_to_one,
|
||||
};
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
+18
-16
@@ -95,13 +95,22 @@ struct ec_method_st {
|
||||
int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *,
|
||||
BIGNUM *x, BIGNUM *y, BN_CTX *);
|
||||
|
||||
/* used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
|
||||
* EC_POINT_have_precompute_mult
|
||||
* (default implementations are used if the 'mul' pointer is 0): */
|
||||
int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int (*precompute_mult)(EC_GROUP *group, BN_CTX *);
|
||||
/* Computes |r = g_scalar*generator + p_scalar*p| if |g_scalar| and |p_scalar|
|
||||
* are both non-null. Computes |r = g_scalar*generator| if |p_scalar| is null.
|
||||
* Computes |r = p_scalar*p| if g_scalar is null. At least one of |g_scalar|
|
||||
* and |p_scalar| must be non-null, and |p| must be non-null if |p_scalar| is
|
||||
* non-null. */
|
||||
int (*mul)(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx);
|
||||
|
||||
/* |check_pub_key_order| checks that the public key is in the proper subgroup
|
||||
* by checking that |pub_key*group->order| is the point at infinity. This may
|
||||
* be NULL for |EC_METHOD|s specialized for prime-order curves (i.e. with
|
||||
* cofactor one), as this check is not necessary for such curves (See section
|
||||
* A.3 of the NSA's "Suite B Implementer's Guide to FIPS 186-3
|
||||
* (ECDSA)"). */
|
||||
int (*check_pub_key_order)(const EC_GROUP *group, const EC_POINT *pub_key,
|
||||
BN_CTX *ctx);
|
||||
|
||||
/* internal functions */
|
||||
|
||||
@@ -121,10 +130,6 @@ struct ec_method_st {
|
||||
|
||||
const EC_METHOD* EC_GFp_mont_method(void);
|
||||
|
||||
struct ec_pre_comp_st;
|
||||
void ec_pre_comp_free(struct ec_pre_comp_st *pre_comp);
|
||||
void *ec_pre_comp_dup(struct ec_pre_comp_st *pre_comp);
|
||||
|
||||
struct ec_group_st {
|
||||
const EC_METHOD *meth;
|
||||
|
||||
@@ -133,7 +138,6 @@ struct ec_group_st {
|
||||
|
||||
int curve_name; /* optional NID for named curve */
|
||||
|
||||
struct ec_pre_comp_st *pre_comp;
|
||||
const BN_MONT_CTX *mont_data; /* data for ECDSA inverse */
|
||||
|
||||
/* The following members are handled by the method functions,
|
||||
@@ -170,10 +174,8 @@ int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src);
|
||||
* a built-in group. */
|
||||
const BN_MONT_CTX *ec_group_get_mont_data(const EC_GROUP *group);
|
||||
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx);
|
||||
|
||||
/* method functions in simple.c */
|
||||
int ec_GFp_simple_group_init(EC_GROUP *);
|
||||
|
||||
+6
-32
@@ -90,18 +90,10 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
if (EC_POINT_is_at_infinity(group, point)) {
|
||||
/* encodes to a single 0 octet */
|
||||
if (buf != NULL) {
|
||||
if (len < 1) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
|
||||
return 0;
|
||||
}
|
||||
buf[0] = 0;
|
||||
}
|
||||
return 1;
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
/* ret := required output buffer length */
|
||||
field_len = BN_num_bytes(&group->field);
|
||||
ret =
|
||||
@@ -117,7 +109,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,24 +185,12 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
form = buf[0];
|
||||
y_bit = form & 1;
|
||||
form = form & ~1U;
|
||||
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
|
||||
(form != POINT_CONVERSION_UNCOMPRESSED)) {
|
||||
if ((form != POINT_CONVERSION_COMPRESSED &&
|
||||
form != POINT_CONVERSION_UNCOMPRESSED) ||
|
||||
(form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (form == 0) {
|
||||
if (len != 1) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return EC_POINT_set_to_infinity(group, point);
|
||||
}
|
||||
|
||||
field_len = BN_num_bytes(&group->field);
|
||||
enc_len =
|
||||
@@ -261,12 +241,6 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
|
||||
}
|
||||
}
|
||||
|
||||
/* test required by X9.62 */
|
||||
if (!EC_POINT_is_on_curve(group, point, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
|
||||
+23
-59
@@ -106,7 +106,7 @@ static const felem_bytearray nistp224_curve_params[5] = {
|
||||
* The reason for this is so that we can clock bits into four different
|
||||
* locations when doing simple scalar multiplies against the base point,
|
||||
* and then another four locations using the second 16 elements. */
|
||||
static const felem gmul[2][16][3] = {
|
||||
static const felem g_pre_comp[2][16][3] = {
|
||||
{{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
|
||||
{0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
|
||||
@@ -937,8 +937,7 @@ static char get_bit(const felem_bytearray in, unsigned i) {
|
||||
static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
const felem_bytearray scalars[],
|
||||
const unsigned num_points, const u8 *g_scalar,
|
||||
const int mixed, const felem pre_comp[][17][3],
|
||||
const felem g_pre_comp[2][16][3]) {
|
||||
const int mixed, const felem pre_comp[][17][3]) {
|
||||
int i, skip;
|
||||
unsigned num;
|
||||
unsigned gen_mul = (g_scalar != NULL);
|
||||
@@ -1122,12 +1121,16 @@ static void make_points_affine(size_t num, felem points[/*num*/][3],
|
||||
(void (*)(void *, const void *))felem_contract);
|
||||
}
|
||||
|
||||
/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL values
|
||||
* Result is stored in r (r can equal one of the inputs). */
|
||||
int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[], BN_CTX *ctx) {
|
||||
const BIGNUM *g_scalar, const EC_POINT *p_,
|
||||
const BIGNUM *p_scalar_, BN_CTX *ctx) {
|
||||
/* TODO: This function used to take |points| and |scalars| as arrays of
|
||||
* |num| elements. The code below should be simplified to work in terms of
|
||||
* |p_| and |p_scalar_|. */
|
||||
size_t num = p_ != NULL ? 1 : 0;
|
||||
const EC_POINT **points = p_ != NULL ? &p_ : NULL;
|
||||
BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
|
||||
|
||||
int ret = 0;
|
||||
int j;
|
||||
unsigned i;
|
||||
@@ -1140,11 +1143,8 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
felem *tmp_felems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned num_bytes;
|
||||
int have_pre_comp = 0;
|
||||
size_t num_points = num;
|
||||
felem x_in, y_in, z_in, x_out, y_out, z_out;
|
||||
const felem(*g_pre_comp)[16][3] = NULL;
|
||||
EC_POINT *generator = NULL;
|
||||
const EC_POINT *p = NULL;
|
||||
const BIGNUM *p_scalar = NULL;
|
||||
|
||||
@@ -1164,35 +1164,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (scalar != NULL) {
|
||||
/* try to use the standard precomputation */
|
||||
g_pre_comp = &gmul[0];
|
||||
generator = EC_POINT_new(group);
|
||||
if (generator == NULL) {
|
||||
goto err;
|
||||
}
|
||||
/* get the generator from precomputation */
|
||||
if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
|
||||
!felem_to_BN(y, g_pre_comp[0][1][1]) ||
|
||||
!felem_to_BN(z, g_pre_comp[0][1][2])) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z,
|
||||
ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
|
||||
/* precomputation matches generator */
|
||||
have_pre_comp = 1;
|
||||
} else {
|
||||
/* we don't have valid precomputation:
|
||||
* treat the generator as a random point */
|
||||
num_points = num_points + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_points > 0) {
|
||||
if (num_points >= 3) {
|
||||
/* unless we precompute multiples for just one or two points,
|
||||
@@ -1200,7 +1171,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
mixed = 1;
|
||||
}
|
||||
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
|
||||
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem));
|
||||
pre_comp = OPENSSL_malloc(num_points * sizeof(felem[17][3]));
|
||||
if (mixed) {
|
||||
tmp_felems = OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem));
|
||||
}
|
||||
@@ -1219,7 +1190,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
if (i == num) {
|
||||
/* the generator */
|
||||
p = EC_GROUP_get0_generator(group);
|
||||
p_scalar = scalar;
|
||||
p_scalar = g_scalar;
|
||||
} else {
|
||||
/* the i^th point */
|
||||
p = points[i];
|
||||
@@ -1227,7 +1198,7 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
}
|
||||
|
||||
if (p_scalar != NULL && p != NULL) {
|
||||
/* reduce scalar to 0 <= scalar < 2^224 */
|
||||
/* reduce g_scalar to 0 <= g_scalar < 2^224 */
|
||||
if (BN_num_bits(p_scalar) > 224 || BN_is_negative(p_scalar)) {
|
||||
/* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness */
|
||||
@@ -1272,31 +1243,25 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
}
|
||||
}
|
||||
|
||||
/* the scalar for the generator */
|
||||
if (scalar != NULL && have_pre_comp) {
|
||||
if (g_scalar != NULL) {
|
||||
memset(g_secret, 0, sizeof(g_secret));
|
||||
/* reduce scalar to 0 <= scalar < 2^224 */
|
||||
if (BN_num_bits(scalar) > 224 || BN_is_negative(scalar)) {
|
||||
/* reduce g_scalar to 0 <= g_scalar < 2^224 */
|
||||
if (BN_num_bits(g_scalar) > 224 || BN_is_negative(g_scalar)) {
|
||||
/* this is an unusual input, and we don't guarantee constant-timeness */
|
||||
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else {
|
||||
num_bytes = BN_bn2bin(scalar, tmp);
|
||||
num_bytes = BN_bn2bin(g_scalar, tmp);
|
||||
}
|
||||
|
||||
flip_endian(g_secret, tmp, num_bytes);
|
||||
/* do the multiplication with generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
|
||||
num_points, g_secret, mixed, (const felem(*)[17][3])pre_comp,
|
||||
g_pre_comp);
|
||||
} else {
|
||||
/* do the multiplication without generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
|
||||
num_points, NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
|
||||
}
|
||||
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
|
||||
num_points, g_scalar != NULL ? g_secret : NULL, mixed,
|
||||
(const felem(*)[17][3])pre_comp);
|
||||
|
||||
/* reduce the output to its unique minimal representation */
|
||||
felem_contract(x_in, x_out);
|
||||
@@ -1312,7 +1277,6 @@ int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
OPENSSL_free(secrets);
|
||||
OPENSSL_free(pre_comp);
|
||||
@@ -1328,7 +1292,7 @@ const EC_METHOD *EC_GFp_nistp224_method(void) {
|
||||
ec_GFp_nistp224_group_set_curve,
|
||||
ec_GFp_nistp224_point_get_affine_coordinates,
|
||||
ec_GFp_nistp224_points_mul,
|
||||
0 /* precompute_mult */,
|
||||
0 /* check_pub_key_order */,
|
||||
ec_GFp_simple_field_mul,
|
||||
ec_GFp_simple_field_sqr,
|
||||
0 /* field_encode */,
|
||||
|
||||
+24
-65
@@ -1312,8 +1312,8 @@ static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
|
||||
*
|
||||
* Tables for other points have table[i] = iG for i in 0 .. 16. */
|
||||
|
||||
/* gmul is the table of precomputed base points */
|
||||
static const smallfelem gmul[2][16][3] = {
|
||||
/* g_pre_comp is the table of precomputed base points */
|
||||
static const smallfelem g_pre_comp[2][16][3] = {
|
||||
{{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
|
||||
0x6b17d1f2e12c4247},
|
||||
@@ -1505,8 +1505,7 @@ static char get_bit(const felem_bytearray in, int i) {
|
||||
static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
const felem_bytearray scalars[],
|
||||
const unsigned num_points, const u8 *g_scalar,
|
||||
const int mixed, const smallfelem pre_comp[][17][3],
|
||||
const smallfelem g_pre_comp[2][16][3]) {
|
||||
const int mixed, const smallfelem pre_comp[][17][3]) {
|
||||
int i, skip;
|
||||
unsigned num, gen_mul = (g_scalar != NULL);
|
||||
felem nq[3], ftmp;
|
||||
@@ -1598,11 +1597,6 @@ static void batch_mul(felem x_out, felem y_out, felem z_out,
|
||||
felem_assign(z_out, nq[2]);
|
||||
}
|
||||
|
||||
/* Precomputation for the group generator. */
|
||||
typedef struct {
|
||||
smallfelem g_pre_comp[2][16][3];
|
||||
} NISTP256_PRE_COMP;
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
* OPENSSL EC_METHOD FUNCTIONS
|
||||
@@ -1707,12 +1701,16 @@ static void make_points_affine(size_t num, smallfelem points[][3],
|
||||
(void (*)(void *, const void *))smallfelem_assign);
|
||||
}
|
||||
|
||||
/* Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
|
||||
* values Result is stored in r (r can equal one of the inputs). */
|
||||
int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[], BN_CTX *ctx) {
|
||||
const BIGNUM *g_scalar, const EC_POINT *p_,
|
||||
const BIGNUM *p_scalar_, BN_CTX *ctx) {
|
||||
/* TODO: This function used to take |points| and |scalars| as arrays of
|
||||
* |num| elements. The code below should be simplified to work in terms of |p|
|
||||
* and |p_scalar|. */
|
||||
size_t num = p_ != NULL ? 1 : 0;
|
||||
const EC_POINT **points = p_ != NULL ? &p_ : NULL;
|
||||
BIGNUM const *const *scalars = p_ != NULL ? &p_scalar_ : NULL;
|
||||
|
||||
int ret = 0;
|
||||
int j;
|
||||
int mixed = 0;
|
||||
@@ -1724,12 +1722,9 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
smallfelem *tmp_smallfelems = NULL;
|
||||
felem_bytearray tmp;
|
||||
unsigned i, num_bytes;
|
||||
int have_pre_comp = 0;
|
||||
size_t num_points = num;
|
||||
smallfelem x_in, y_in, z_in;
|
||||
felem x_out, y_out, z_out;
|
||||
const smallfelem(*g_pre_comp)[16][3] = NULL;
|
||||
EC_POINT *generator = NULL;
|
||||
const EC_POINT *p = NULL;
|
||||
const BIGNUM *p_scalar = NULL;
|
||||
|
||||
@@ -1748,34 +1743,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (scalar != NULL) {
|
||||
/* try to use the standard precomputation */
|
||||
g_pre_comp = &gmul[0];
|
||||
generator = EC_POINT_new(group);
|
||||
if (generator == NULL) {
|
||||
goto err;
|
||||
}
|
||||
/* get the generator from precomputation */
|
||||
if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
|
||||
!smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
|
||||
!smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z,
|
||||
ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
|
||||
/* precomputation matches generator */
|
||||
have_pre_comp = 1;
|
||||
} else {
|
||||
/* we don't have valid precomputation: treat the generator as a
|
||||
* random point. */
|
||||
num_points++;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_points > 0) {
|
||||
if (num_points >= 3) {
|
||||
/* unless we precompute multiples for just one or two points,
|
||||
@@ -1783,7 +1750,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
mixed = 1;
|
||||
}
|
||||
secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray));
|
||||
pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem));
|
||||
pre_comp = OPENSSL_malloc(num_points * sizeof(smallfelem[17][3]));
|
||||
if (mixed) {
|
||||
tmp_smallfelems =
|
||||
OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem));
|
||||
@@ -1802,14 +1769,14 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
if (i == num) {
|
||||
/* we didn't have a valid precomputation, so we pick the generator. */
|
||||
p = EC_GROUP_get0_generator(group);
|
||||
p_scalar = scalar;
|
||||
p_scalar = g_scalar;
|
||||
} else {
|
||||
/* the i^th point */
|
||||
p = points[i];
|
||||
p_scalar = scalars[i];
|
||||
}
|
||||
if (p_scalar != NULL && p != NULL) {
|
||||
/* reduce scalar to 0 <= scalar < 2^256 */
|
||||
/* reduce g_scalar to 0 <= g_scalar < 2^256 */
|
||||
if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
|
||||
/* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness. */
|
||||
@@ -1851,32 +1818,25 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
}
|
||||
}
|
||||
|
||||
/* the scalar for the generator */
|
||||
if (scalar != NULL && have_pre_comp) {
|
||||
if (g_scalar != NULL) {
|
||||
memset(g_secret, 0, sizeof(g_secret));
|
||||
/* reduce scalar to 0 <= scalar < 2^256 */
|
||||
if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) {
|
||||
/* reduce g_scalar to 0 <= g_scalar < 2^256 */
|
||||
if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
|
||||
/* this is an unusual input, and we don't guarantee
|
||||
* constant-timeness. */
|
||||
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
|
||||
if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
num_bytes = BN_bn2bin(tmp_scalar, tmp);
|
||||
} else {
|
||||
num_bytes = BN_bn2bin(scalar, tmp);
|
||||
num_bytes = BN_bn2bin(g_scalar, tmp);
|
||||
}
|
||||
flip_endian(g_secret, tmp, num_bytes);
|
||||
/* do the multiplication with generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
|
||||
num_points, g_secret, mixed, (const smallfelem(*)[17][3])pre_comp,
|
||||
g_pre_comp);
|
||||
} else {
|
||||
/* do the multiplication without generator precomputation */
|
||||
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
|
||||
num_points, NULL, mixed, (const smallfelem(*)[17][3])pre_comp,
|
||||
NULL);
|
||||
}
|
||||
batch_mul(x_out, y_out, z_out, (const felem_bytearray(*))secrets,
|
||||
num_points, g_scalar != NULL ? g_secret : NULL, mixed,
|
||||
(const smallfelem(*)[17][3])pre_comp);
|
||||
|
||||
/* reduce the output to its unique minimal representation */
|
||||
felem_contract(x_in, x_out);
|
||||
@@ -1892,7 +1852,6 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
EC_POINT_free(generator);
|
||||
BN_CTX_free(new_ctx);
|
||||
OPENSSL_free(secrets);
|
||||
OPENSSL_free(pre_comp);
|
||||
@@ -1908,7 +1867,7 @@ const EC_METHOD *EC_GFp_nistp256_method(void) {
|
||||
ec_GFp_simple_group_copy, ec_GFp_nistp256_group_set_curve,
|
||||
ec_GFp_nistp256_point_get_affine_coordinates,
|
||||
ec_GFp_nistp256_points_mul,
|
||||
0 /* precompute_mult */,
|
||||
0 /* check_pub_key_order */,
|
||||
ec_GFp_simple_field_mul, ec_GFp_simple_field_sqr,
|
||||
0 /* field_encode */, 0 /* field_decode */, 0 /* field_set_to_one */
|
||||
};
|
||||
|
||||
+205
-310
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -37,18 +38,13 @@
|
||||
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
|
||||
!defined(OPENSSL_SMALL)
|
||||
|
||||
#if BN_BITS2 != 64
|
||||
#define TOBN(hi, lo) lo, hi
|
||||
#else
|
||||
#define TOBN(hi, lo) ((BN_ULONG)hi << 32 | lo)
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define ALIGN32 __attribute((aligned(32)))
|
||||
#define ALIGN(x) __attribute((aligned(x)))
|
||||
#elif defined(_MSC_VER)
|
||||
#define ALIGN32 __declspec(align(32))
|
||||
#define ALIGN(x) __declspec(align(x))
|
||||
#else
|
||||
#define ALIGN32
|
||||
#define ALIGN(x)
|
||||
#endif
|
||||
|
||||
#define ALIGNPTR(p, N) ((uint8_t *)p + N - (size_t)p % N)
|
||||
@@ -69,21 +65,6 @@ typedef P256_POINT_AFFINE PRECOMP256_ROW[64];
|
||||
|
||||
/* Functions implemented in assembly */
|
||||
|
||||
/* Modular mul by 2: res = 2*a mod P */
|
||||
void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS]);
|
||||
/* Modular div by 2: res = a/2 mod P */
|
||||
void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS]);
|
||||
/* Modular mul by 3: res = 3*a mod P */
|
||||
void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG a[P256_LIMBS]);
|
||||
/* Modular add: res = a+b mod P */
|
||||
void ecp_nistz256_add(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS],
|
||||
const BN_ULONG b[P256_LIMBS]);
|
||||
/* Modular sub: res = a-b mod P */
|
||||
void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS],
|
||||
const BN_ULONG b[P256_LIMBS]);
|
||||
/* Modular neg: res = -a mod P */
|
||||
void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]);
|
||||
/* Montgomery mul: res = a*b*2^-256 mod P */
|
||||
@@ -96,9 +77,6 @@ void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS],
|
||||
/* Convert a number from Montgomery domain, by multiplying with 1 */
|
||||
void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG in[P256_LIMBS]);
|
||||
/* Convert a number to Montgomery domain, by multiplying with 2^512 mod P*/
|
||||
void ecp_nistz256_to_mont(BN_ULONG res[P256_LIMBS],
|
||||
const BN_ULONG in[P256_LIMBS]);
|
||||
/* Functions that perform constant time access to the precomputed tables */
|
||||
void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT *in_t, int index);
|
||||
void ecp_nistz256_select_w7(P256_POINT_AFFINE *val,
|
||||
@@ -153,48 +131,6 @@ static void copy_conditional(BN_ULONG dst[P256_LIMBS],
|
||||
}
|
||||
}
|
||||
|
||||
static BN_ULONG is_zero(BN_ULONG in) {
|
||||
in |= (0 - in);
|
||||
in = ~in;
|
||||
in &= BN_MASK2;
|
||||
in >>= BN_BITS2 - 1;
|
||||
return in;
|
||||
}
|
||||
|
||||
static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS],
|
||||
const BN_ULONG b[P256_LIMBS]) {
|
||||
BN_ULONG res;
|
||||
|
||||
res = a[0] ^ b[0];
|
||||
res |= a[1] ^ b[1];
|
||||
res |= a[2] ^ b[2];
|
||||
res |= a[3] ^ b[3];
|
||||
if (P256_LIMBS == 8) {
|
||||
res |= a[4] ^ b[4];
|
||||
res |= a[5] ^ b[5];
|
||||
res |= a[6] ^ b[6];
|
||||
res |= a[7] ^ b[7];
|
||||
}
|
||||
|
||||
return is_zero(res);
|
||||
}
|
||||
|
||||
static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS]) {
|
||||
BN_ULONG res;
|
||||
|
||||
res = a[0] ^ ONE[0];
|
||||
res |= a[1] ^ ONE[1];
|
||||
res |= a[2] ^ ONE[2];
|
||||
res |= a[3] ^ ONE[3];
|
||||
if (P256_LIMBS == 8) {
|
||||
res |= a[4] ^ ONE[4];
|
||||
res |= a[5] ^ ONE[5];
|
||||
res |= a[6] ^ ONE[6];
|
||||
}
|
||||
|
||||
return is_zero(res);
|
||||
}
|
||||
|
||||
void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a);
|
||||
void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a,
|
||||
const P256_POINT *b);
|
||||
@@ -296,113 +232,117 @@ static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS],
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* r = sum(scalar[i]*point[i]) */
|
||||
static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
const BIGNUM **scalar,
|
||||
const EC_POINT **point, int num,
|
||||
BN_CTX *ctx) {
|
||||
/* r = p * p_scalar */
|
||||
static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
const EC_POINT *p, const BIGNUM *p_scalar,
|
||||
BN_CTX *ctx) {
|
||||
assert(p != NULL);
|
||||
assert(p_scalar != NULL);
|
||||
|
||||
static const unsigned kWindowSize = 5;
|
||||
static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1;
|
||||
|
||||
void *table_storage = OPENSSL_malloc(num * 16 * sizeof(P256_POINT) + 64);
|
||||
uint8_t(*p_str)[33] = OPENSSL_malloc(num * 33 * sizeof(uint8_t));
|
||||
const BIGNUM **scalars = OPENSSL_malloc(num * sizeof(BIGNUM *));
|
||||
/* A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should
|
||||
* add no more than 63 bytes of overhead. Thus, |table| should require
|
||||
* ~1599 ((96 * 16) + 63) bytes of stack space. */
|
||||
ALIGN(64) P256_POINT table[16];
|
||||
uint8_t p_str[33];
|
||||
|
||||
if (table_storage == NULL ||
|
||||
p_str == NULL ||
|
||||
scalars == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
int ret = 0;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int ctx_started = 0;
|
||||
|
||||
if (BN_num_bits(p_scalar) > 256 || BN_is_negative(p_scalar)) {
|
||||
if (ctx == NULL) {
|
||||
new_ctx = BN_CTX_new();
|
||||
if (new_ctx == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ctx = new_ctx;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
ctx_started = 1;
|
||||
BIGNUM *mod = BN_CTX_get(ctx);
|
||||
if (mod == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!BN_nnmod(mod, p_scalar, &group->order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
p_scalar = mod;
|
||||
}
|
||||
|
||||
int j;
|
||||
for (j = 0; j < p_scalar->top * BN_BYTES; j += BN_BYTES) {
|
||||
BN_ULONG d = p_scalar->d[j / BN_BYTES];
|
||||
|
||||
p_str[j + 0] = d & 0xff;
|
||||
p_str[j + 1] = (d >> 8) & 0xff;
|
||||
p_str[j + 2] = (d >> 16) & 0xff;
|
||||
p_str[j + 3] = (d >>= 24) & 0xff;
|
||||
if (BN_BYTES == 8) {
|
||||
d >>= 8;
|
||||
p_str[j + 4] = d & 0xff;
|
||||
p_str[j + 5] = (d >> 8) & 0xff;
|
||||
p_str[j + 6] = (d >> 16) & 0xff;
|
||||
p_str[j + 7] = (d >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
for (; j < 33; j++) {
|
||||
p_str[j] = 0;
|
||||
}
|
||||
|
||||
/* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
|
||||
* not stored. All other values are actually stored with an offset of -1 in
|
||||
* table. */
|
||||
P256_POINT *row = table;
|
||||
|
||||
if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) ||
|
||||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) ||
|
||||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
P256_POINT(*table)[16] = (void *)ALIGNPTR(table_storage, 64);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < num; i++) {
|
||||
P256_POINT *row = table[i];
|
||||
|
||||
if (BN_num_bits(scalar[i]) > 256 || BN_is_negative(scalar[i])) {
|
||||
BIGNUM *mod = BN_CTX_get(ctx);
|
||||
if (mod == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_nnmod(mod, scalar[i], &group->order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
scalars[i] = mod;
|
||||
} else {
|
||||
scalars[i] = scalar[i];
|
||||
}
|
||||
|
||||
int j;
|
||||
for (j = 0; j < scalars[i]->top * BN_BYTES; j += BN_BYTES) {
|
||||
BN_ULONG d = scalars[i]->d[j / BN_BYTES];
|
||||
|
||||
p_str[i][j + 0] = d & 0xff;
|
||||
p_str[i][j + 1] = (d >> 8) & 0xff;
|
||||
p_str[i][j + 2] = (d >> 16) & 0xff;
|
||||
p_str[i][j + 3] = (d >>= 24) & 0xff;
|
||||
if (BN_BYTES == 8) {
|
||||
d >>= 8;
|
||||
p_str[i][j + 4] = d & 0xff;
|
||||
p_str[i][j + 5] = (d >> 8) & 0xff;
|
||||
p_str[i][j + 6] = (d >> 16) & 0xff;
|
||||
p_str[i][j + 7] = (d >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
for (; j < 33; j++) {
|
||||
p_str[i][j] = 0;
|
||||
}
|
||||
|
||||
/* table[0] is implicitly (0,0,0) (the point at infinity), therefore it is
|
||||
* not stored. All other values are actually stored with an offset of -1 in
|
||||
* table. */
|
||||
|
||||
if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &point[i]->X) ||
|
||||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &point[i]->Y) ||
|
||||
!ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &point[i]->Z)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
|
||||
ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
|
||||
ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
|
||||
ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
|
||||
ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
|
||||
ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
|
||||
ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
|
||||
}
|
||||
ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]);
|
||||
ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]);
|
||||
ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]);
|
||||
ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]);
|
||||
ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]);
|
||||
ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]);
|
||||
ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]);
|
||||
ecp_nistz256_point_add(&row[16 - 1], &row[15 - 1], &row[1 - 1]);
|
||||
|
||||
BN_ULONG tmp[P256_LIMBS];
|
||||
ALIGN32 P256_POINT h;
|
||||
ALIGN(32) P256_POINT h;
|
||||
unsigned index = 255;
|
||||
unsigned wvalue = p_str[0][(index - 1) / 8];
|
||||
unsigned wvalue = p_str[(index - 1) / 8];
|
||||
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
|
||||
|
||||
ecp_nistz256_select_w5(r, table[0], booth_recode_w5(wvalue) >> 1);
|
||||
ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1);
|
||||
|
||||
while (index >= 5) {
|
||||
for (i = (index == 255 ? 1 : 0); i < num; i++) {
|
||||
if (index != 255) {
|
||||
unsigned off = (index - 1) / 8;
|
||||
|
||||
wvalue = p_str[i][off] | p_str[i][off + 1] << 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
|
||||
|
||||
wvalue = booth_recode_w5(wvalue);
|
||||
|
||||
ecp_nistz256_select_w5(&h, table[i], wvalue >> 1);
|
||||
ecp_nistz256_select_w5(&h, table, wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(tmp, h.Y);
|
||||
copy_conditional(h.Y, tmp, (wvalue & 1));
|
||||
@@ -420,217 +360,166 @@ static void ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r,
|
||||
}
|
||||
|
||||
/* Final window */
|
||||
for (i = 0; i < num; i++) {
|
||||
wvalue = p_str[i][0];
|
||||
wvalue = (wvalue << 1) & kMask;
|
||||
wvalue = p_str[0];
|
||||
wvalue = (wvalue << 1) & kMask;
|
||||
|
||||
wvalue = booth_recode_w5(wvalue);
|
||||
wvalue = booth_recode_w5(wvalue);
|
||||
|
||||
ecp_nistz256_select_w5(&h, table[i], wvalue >> 1);
|
||||
ecp_nistz256_select_w5(&h, table, wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(tmp, h.Y);
|
||||
copy_conditional(h.Y, tmp, wvalue & 1);
|
||||
ecp_nistz256_neg(tmp, h.Y);
|
||||
copy_conditional(h.Y, tmp, wvalue & 1);
|
||||
|
||||
ecp_nistz256_point_add(r, r, &h);
|
||||
}
|
||||
ecp_nistz256_point_add(r, r, &h);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(table_storage);
|
||||
OPENSSL_free(p_str);
|
||||
OPENSSL_free((BIGNUM**) scalars);
|
||||
if (ctx_started) {
|
||||
BN_CTX_end(ctx);
|
||||
}
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Coordinates of G, for which we have precomputed tables */
|
||||
const static BN_ULONG def_xG[P256_LIMBS] = {
|
||||
TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601),
|
||||
TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6),
|
||||
};
|
||||
|
||||
const static BN_ULONG def_yG[P256_LIMBS] = {
|
||||
TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c),
|
||||
TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85)
|
||||
};
|
||||
|
||||
/* ecp_nistz256_is_affine_G returns one if |generator| is the standard, P-256
|
||||
* generator. */
|
||||
static int ecp_nistz256_is_affine_G(const EC_POINT *generator) {
|
||||
return (generator->X.top == P256_LIMBS) && (generator->Y.top == P256_LIMBS) &&
|
||||
(generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) &&
|
||||
is_equal(generator->X.d, def_xG) && is_equal(generator->Y.d, def_yG) &&
|
||||
is_one(generator->Z.d);
|
||||
}
|
||||
|
||||
/* r = scalar*G + sum(scalars[i]*points[i]) */
|
||||
static int ecp_nistz256_points_mul(
|
||||
const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx) {
|
||||
const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *p_, const BIGNUM *p_scalar, BN_CTX *ctx) {
|
||||
assert((p_ != NULL) == (p_scalar != NULL));
|
||||
|
||||
static const unsigned kWindowSize = 7;
|
||||
static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1;
|
||||
|
||||
int ret = 0, no_precomp_for_generator = 0, p_is_infinity = 0;
|
||||
ALIGN32 union {
|
||||
ALIGN(32) union {
|
||||
P256_POINT p;
|
||||
P256_POINT_AFFINE a;
|
||||
} t, p;
|
||||
|
||||
if (scalar == NULL && num == 0) {
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
int ret = 0;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
int ctx_started = 0;
|
||||
|
||||
/* Need 256 bits for space for all coordinates. */
|
||||
bn_wexpand(&r->X, P256_LIMBS);
|
||||
bn_wexpand(&r->Y, P256_LIMBS);
|
||||
bn_wexpand(&r->Z, P256_LIMBS);
|
||||
if (bn_wexpand(&r->X, P256_LIMBS) == NULL ||
|
||||
bn_wexpand(&r->Y, P256_LIMBS) == NULL ||
|
||||
bn_wexpand(&r->Z, P256_LIMBS) == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
r->X.top = P256_LIMBS;
|
||||
r->Y.top = P256_LIMBS;
|
||||
r->Z.top = P256_LIMBS;
|
||||
|
||||
const EC_POINT *generator = NULL;
|
||||
if (scalar) {
|
||||
generator = EC_GROUP_get0_generator(group);
|
||||
if (generator == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
if (g_scalar != NULL) {
|
||||
if (BN_num_bits(g_scalar) > 256 || BN_is_negative(g_scalar)) {
|
||||
if (ctx == NULL) {
|
||||
new_ctx = BN_CTX_new();
|
||||
if (new_ctx == NULL) {
|
||||
goto err;
|
||||
}
|
||||
ctx = new_ctx;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
ctx_started = 1;
|
||||
BIGNUM *tmp_scalar = BN_CTX_get(ctx);
|
||||
if (tmp_scalar == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BN_nnmod(tmp_scalar, g_scalar, &group->order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
g_scalar = tmp_scalar;
|
||||
}
|
||||
|
||||
if (ecp_nistz256_is_affine_G(generator)) {
|
||||
if (BN_num_bits(scalar) > 256 || BN_is_negative(scalar)) {
|
||||
BIGNUM *tmp_scalar = BN_CTX_get(ctx);
|
||||
if (tmp_scalar == NULL) {
|
||||
goto err;
|
||||
}
|
||||
uint8_t p_str[33] = {0};
|
||||
int i;
|
||||
for (i = 0; i < g_scalar->top * BN_BYTES; i += BN_BYTES) {
|
||||
BN_ULONG d = g_scalar->d[i / BN_BYTES];
|
||||
|
||||
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
scalar = tmp_scalar;
|
||||
p_str[i + 0] = d & 0xff;
|
||||
p_str[i + 1] = (d >> 8) & 0xff;
|
||||
p_str[i + 2] = (d >> 16) & 0xff;
|
||||
p_str[i + 3] = (d >>= 24) & 0xff;
|
||||
if (BN_BYTES == 8) {
|
||||
d >>= 8;
|
||||
p_str[i + 4] = d & 0xff;
|
||||
p_str[i + 5] = (d >> 8) & 0xff;
|
||||
p_str[i + 6] = (d >> 16) & 0xff;
|
||||
p_str[i + 7] = (d >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t p_str[33] = {0};
|
||||
int i;
|
||||
for (i = 0; i < scalar->top * BN_BYTES; i += BN_BYTES) {
|
||||
BN_ULONG d = scalar->d[i / BN_BYTES];
|
||||
for (; i < (int) sizeof(p_str); i++) {
|
||||
p_str[i] = 0;
|
||||
}
|
||||
|
||||
p_str[i + 0] = d & 0xff;
|
||||
p_str[i + 1] = (d >> 8) & 0xff;
|
||||
p_str[i + 2] = (d >> 16) & 0xff;
|
||||
p_str[i + 3] = (d >>= 24) & 0xff;
|
||||
if (BN_BYTES == 8) {
|
||||
d >>= 8;
|
||||
p_str[i + 4] = d & 0xff;
|
||||
p_str[i + 5] = (d >> 8) & 0xff;
|
||||
p_str[i + 6] = (d >> 16) & 0xff;
|
||||
p_str[i + 7] = (d >> 24) & 0xff;
|
||||
}
|
||||
}
|
||||
/* First window */
|
||||
unsigned wvalue = (p_str[0] << 1) & kMask;
|
||||
unsigned index = kWindowSize;
|
||||
|
||||
for (; i < (int) sizeof(p_str); i++) {
|
||||
p_str[i] = 0;
|
||||
}
|
||||
wvalue = booth_recode_w7(wvalue);
|
||||
|
||||
/* First window */
|
||||
unsigned wvalue = (p_str[0] << 1) & kMask;
|
||||
unsigned index = kWindowSize;
|
||||
const PRECOMP256_ROW *const precomputed_table =
|
||||
(const PRECOMP256_ROW *)ecp_nistz256_precomputed;
|
||||
ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
|
||||
|
||||
memcpy(p.p.Z, ONE, sizeof(ONE));
|
||||
|
||||
for (i = 1; i < 37; i++) {
|
||||
unsigned off = (index - 1) / 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
|
||||
index += kWindowSize;
|
||||
|
||||
wvalue = booth_recode_w7(wvalue);
|
||||
|
||||
const PRECOMP256_ROW *const precomputed_table =
|
||||
(const PRECOMP256_ROW *)ecp_nistz256_precomputed;
|
||||
ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1);
|
||||
ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(p.p.Z, p.p.Y);
|
||||
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
|
||||
ecp_nistz256_neg(t.p.Z, t.a.Y);
|
||||
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
|
||||
|
||||
memcpy(p.p.Z, ONE, sizeof(ONE));
|
||||
|
||||
for (i = 1; i < 37; i++) {
|
||||
unsigned off = (index - 1) / 8;
|
||||
wvalue = p_str[off] | p_str[off + 1] << 8;
|
||||
wvalue = (wvalue >> ((index - 1) % 8)) & kMask;
|
||||
index += kWindowSize;
|
||||
|
||||
wvalue = booth_recode_w7(wvalue);
|
||||
|
||||
ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1);
|
||||
|
||||
ecp_nistz256_neg(t.p.Z, t.a.Y);
|
||||
copy_conditional(t.a.Y, t.p.Z, wvalue & 1);
|
||||
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
} else {
|
||||
p_is_infinity = 1;
|
||||
no_precomp_for_generator = 1;
|
||||
ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a);
|
||||
}
|
||||
} else {
|
||||
p_is_infinity = 1;
|
||||
}
|
||||
|
||||
if (no_precomp_for_generator) {
|
||||
/* Without a precomputed table for the generator, it has to be handled like
|
||||
* a normal point. */
|
||||
const BIGNUM **new_scalars;
|
||||
const EC_POINT **new_points;
|
||||
|
||||
/* Bound |num| so that all the possible overflows in the following can be
|
||||
* excluded. */
|
||||
if (0xffffff < num) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_scalars = OPENSSL_malloc((num + 1) * sizeof(BIGNUM *));
|
||||
if (new_scalars == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
new_points = OPENSSL_malloc((num + 1) * sizeof(EC_POINT *));
|
||||
if (new_points == NULL) {
|
||||
OPENSSL_free((BIGNUM**) new_scalars);
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy((BIGNUM**) new_scalars, scalars, num * sizeof(BIGNUM *));
|
||||
new_scalars[num] = scalar;
|
||||
memcpy((EC_POINT**) new_points, points, num * sizeof(EC_POINT *));
|
||||
new_points[num] = generator;
|
||||
|
||||
scalars = new_scalars;
|
||||
points = new_points;
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num) {
|
||||
const int p_is_infinity = g_scalar == NULL;
|
||||
if (p_scalar != NULL) {
|
||||
P256_POINT *out = &t.p;
|
||||
if (p_is_infinity) {
|
||||
out = &p.p;
|
||||
}
|
||||
|
||||
ecp_nistz256_windowed_mul(group, out, scalars, points, num, ctx);
|
||||
if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!p_is_infinity) {
|
||||
ecp_nistz256_point_add(&p.p, &p.p, out);
|
||||
}
|
||||
}
|
||||
|
||||
if (no_precomp_for_generator) {
|
||||
OPENSSL_free((BIGNUM **) scalars);
|
||||
OPENSSL_free((EC_POINT **) points);
|
||||
}
|
||||
|
||||
memcpy(r->X.d, p.p.X, sizeof(p.p.X));
|
||||
memcpy(r->Y.d, p.p.Y, sizeof(p.p.Y));
|
||||
memcpy(r->Z.d, p.p.Z, sizeof(p.p.Z));
|
||||
|
||||
/* Not constant-time, but we're only operating on the public output. */
|
||||
bn_correct_top(&r->X);
|
||||
bn_correct_top(&r->Y);
|
||||
bn_correct_top(&r->Z);
|
||||
r->Z_is_one = BN_is_one(&r->Z);
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx_started) {
|
||||
BN_CTX_end(ctx);
|
||||
}
|
||||
BN_CTX_free(new_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -659,7 +548,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
|
||||
ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
|
||||
|
||||
if (x != NULL) {
|
||||
bn_wexpand(x, P256_LIMBS);
|
||||
if (bn_wexpand(x, P256_LIMBS) == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
x->top = P256_LIMBS;
|
||||
ecp_nistz256_from_mont(x->d, x_aff);
|
||||
bn_correct_top(x);
|
||||
@@ -668,7 +560,10 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
|
||||
if (y != NULL) {
|
||||
ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
|
||||
ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
|
||||
bn_wexpand(y, P256_LIMBS);
|
||||
if (bn_wexpand(y, P256_LIMBS) == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
y->top = P256_LIMBS;
|
||||
ecp_nistz256_from_mont(y->d, y_aff);
|
||||
bn_correct_top(y);
|
||||
@@ -686,7 +581,7 @@ const EC_METHOD *EC_GFp_nistz256_method(void) {
|
||||
ec_GFp_mont_group_set_curve,
|
||||
ecp_nistz256_get_affine,
|
||||
ecp_nistz256_points_mul,
|
||||
0, /* precompute_mult */
|
||||
0 /* check_pub_key_order */,
|
||||
ec_GFp_mont_field_mul,
|
||||
ec_GFp_mont_field_sqr,
|
||||
ec_GFp_mont_field_encode,
|
||||
|
||||
@@ -76,25 +76,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
const EC_METHOD *EC_GFp_simple_method(void) {
|
||||
static const EC_METHOD ret = {ec_GFp_simple_group_init,
|
||||
ec_GFp_simple_group_finish,
|
||||
ec_GFp_simple_group_clear_finish,
|
||||
ec_GFp_simple_group_copy,
|
||||
ec_GFp_simple_group_set_curve,
|
||||
ec_GFp_simple_point_get_affine_coordinates,
|
||||
0 /* mul */,
|
||||
0 /* precompute_mult */,
|
||||
ec_GFp_simple_field_mul,
|
||||
ec_GFp_simple_field_sqr,
|
||||
0 /* field_encode */,
|
||||
0 /* field_decode */,
|
||||
0 /* field_set_to_one */};
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
/* Most method functions in this file are designed to work with non-trivial
|
||||
* representations of field elements if necessary (see ecp_mont.c): while
|
||||
* standard modular addition and subtraction are used, the field_mul and
|
||||
|
||||
+27
-426
@@ -80,65 +80,8 @@
|
||||
|
||||
/* This file implements the wNAF-based interleaving multi-exponentation method
|
||||
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
|
||||
* for multiplication with precomputation, we use wNAF splitting
|
||||
* (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
|
||||
* */
|
||||
|
||||
/* structure for precomputed multiples of the generator */
|
||||
typedef struct ec_pre_comp_st {
|
||||
size_t blocksize; /* block size for wNAF splitting */
|
||||
size_t numblocks; /* max. number of blocks for which we have precomputation */
|
||||
size_t w; /* window size */
|
||||
EC_POINT **points; /* array with pre-calculated multiples of generator:
|
||||
* 'num' pointers to EC_POINT objects followed by a NULL */
|
||||
size_t num; /* numblocks * 2^(w-1) */
|
||||
CRYPTO_refcount_t references;
|
||||
} EC_PRE_COMP;
|
||||
|
||||
static EC_PRE_COMP *ec_pre_comp_new(void) {
|
||||
EC_PRE_COMP *ret = NULL;
|
||||
|
||||
ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
|
||||
if (!ret) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
ret->blocksize = 8; /* default */
|
||||
ret->numblocks = 0;
|
||||
ret->w = 4; /* default */
|
||||
ret->points = NULL;
|
||||
ret->num = 0;
|
||||
ret->references = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *ec_pre_comp_dup(EC_PRE_COMP *pre_comp) {
|
||||
if (pre_comp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CRYPTO_refcount_inc(&pre_comp->references);
|
||||
return pre_comp;
|
||||
}
|
||||
|
||||
void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
|
||||
if (pre_comp == NULL ||
|
||||
!CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pre_comp->points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = pre_comp->points; *p != NULL; p++) {
|
||||
EC_POINT_free(*p);
|
||||
}
|
||||
OPENSSL_free(pre_comp->points);
|
||||
}
|
||||
OPENSSL_free(pre_comp);
|
||||
}
|
||||
|
||||
|
||||
/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
|
||||
* This is an array r[] of values that are either zero or odd with an
|
||||
* absolute value less than 2^w satisfying
|
||||
@@ -281,21 +224,12 @@ err:
|
||||
? 2 \
|
||||
: 1))
|
||||
|
||||
/* Compute
|
||||
* \sum scalars[i]*points[i],
|
||||
* also including
|
||||
* scalar*generator
|
||||
* in the addition if scalar != NULL
|
||||
*/
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *ctx) {
|
||||
int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
|
||||
const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) {
|
||||
BN_CTX *new_ctx = NULL;
|
||||
const EC_POINT *generator = NULL;
|
||||
EC_POINT *tmp = NULL;
|
||||
size_t totalnum;
|
||||
size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
|
||||
size_t pre_points_per_block = 0;
|
||||
size_t total_num;
|
||||
size_t i, j;
|
||||
int k;
|
||||
int r_is_inverted = 0;
|
||||
@@ -307,30 +241,9 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t num_val;
|
||||
EC_POINT **val = NULL; /* precomputation */
|
||||
EC_POINT **v;
|
||||
EC_POINT ***val_sub =
|
||||
NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
|
||||
const EC_PRE_COMP *pre_comp = NULL;
|
||||
int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like
|
||||
* other scalars,
|
||||
* i.e. precomputation is not available */
|
||||
EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' */
|
||||
int ret = 0;
|
||||
|
||||
if (group->meth != r->meth) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((scalar == NULL) && (num == 0)) {
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (group->meth != points[i]->meth) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
@@ -338,52 +251,31 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
}
|
||||
}
|
||||
|
||||
if (scalar != NULL) {
|
||||
/* TODO: This function used to take |points| and |scalars| as arrays of
|
||||
* |num| elements. The code below should be simplified to work in terms of |p|
|
||||
* and |p_scalar|. */
|
||||
size_t num = p != NULL ? 1 : 0;
|
||||
const EC_POINT **points = p != NULL ? &p : NULL;
|
||||
const BIGNUM **scalars = p != NULL ? &p_scalar : NULL;
|
||||
|
||||
total_num = num;
|
||||
|
||||
if (g_scalar != NULL) {
|
||||
generator = EC_GROUP_get0_generator(group);
|
||||
if (generator == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* look if we can use precomputed multiples of generator */
|
||||
|
||||
pre_comp = group->pre_comp;
|
||||
|
||||
if (pre_comp && pre_comp->numblocks &&
|
||||
(EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
|
||||
blocksize = pre_comp->blocksize;
|
||||
|
||||
/* determine maximum number of blocks that wNAF splitting may yield
|
||||
* (NB: maximum wNAF length is bit length plus one) */
|
||||
numblocks = (BN_num_bits(scalar) / blocksize) + 1;
|
||||
|
||||
/* we cannot use more blocks than we have precomputation for */
|
||||
if (numblocks > pre_comp->numblocks) {
|
||||
numblocks = pre_comp->numblocks;
|
||||
}
|
||||
|
||||
pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
|
||||
|
||||
/* check that pre_comp looks sane */
|
||||
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
/* can't use precomputation */
|
||||
pre_comp = NULL;
|
||||
numblocks = 1;
|
||||
num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
|
||||
}
|
||||
++total_num; /* treat 'g_scalar' like 'num'-th element of 'scalars' */
|
||||
}
|
||||
|
||||
totalnum = num + numblocks;
|
||||
|
||||
wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
|
||||
wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
|
||||
wNAF = OPENSSL_malloc((totalnum + 1) *
|
||||
wsize = OPENSSL_malloc(total_num * sizeof wsize[0]);
|
||||
wNAF_len = OPENSSL_malloc(total_num * sizeof wNAF_len[0]);
|
||||
wNAF = OPENSSL_malloc((total_num + 1) *
|
||||
sizeof wNAF[0]); /* includes space for pivot */
|
||||
val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
|
||||
val_sub = OPENSSL_malloc(total_num * sizeof val_sub[0]);
|
||||
|
||||
/* Ensure wNAF is initialised in case we end up going to err. */
|
||||
if (wNAF) {
|
||||
@@ -398,15 +290,15 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
/* num_val will be the total number of temporarily precomputed points */
|
||||
num_val = 0;
|
||||
|
||||
for (i = 0; i < num + num_scalar; i++) {
|
||||
for (i = 0; i < total_num; i++) {
|
||||
size_t bits;
|
||||
|
||||
bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
|
||||
bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(g_scalar);
|
||||
wsize[i] = EC_window_bits_for_scalar_size(bits);
|
||||
num_val += (size_t)1 << (wsize[i] - 1);
|
||||
wNAF[i + 1] = NULL; /* make sure we always have a pivot */
|
||||
wNAF[i] =
|
||||
compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
|
||||
compute_wNAF((i < num ? scalars[i] : g_scalar), wsize[i], &wNAF_len[i]);
|
||||
if (wNAF[i] == NULL) {
|
||||
goto err;
|
||||
}
|
||||
@@ -415,110 +307,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
}
|
||||
}
|
||||
|
||||
if (numblocks) {
|
||||
/* we go here iff scalar != NULL */
|
||||
|
||||
if (pre_comp == NULL) {
|
||||
if (num_scalar != 1) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/* we have already generated a wNAF for 'scalar' */
|
||||
} else {
|
||||
signed char *tmp_wNAF = NULL;
|
||||
size_t tmp_len = 0;
|
||||
|
||||
if (num_scalar != 0) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* use the window size for which we have precomputation */
|
||||
wsize[num] = pre_comp->w;
|
||||
tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
|
||||
if (!tmp_wNAF) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tmp_len <= max_len) {
|
||||
/* One of the other wNAFs is at least as long
|
||||
* as the wNAF belonging to the generator,
|
||||
* so wNAF splitting will not buy us anything. */
|
||||
|
||||
numblocks = 1; /* don't use wNAF splitting */
|
||||
totalnum = num + numblocks;
|
||||
wNAF[num] = tmp_wNAF;
|
||||
wNAF[num + 1] = NULL;
|
||||
wNAF_len[num] = tmp_len;
|
||||
/* pre_comp->points starts with the points that we need here: */
|
||||
val_sub[num] = pre_comp->points;
|
||||
} else {
|
||||
/* don't include tmp_wNAF directly into wNAF array
|
||||
* - use wNAF splitting and include the blocks */
|
||||
|
||||
signed char *pp;
|
||||
EC_POINT **tmp_points;
|
||||
|
||||
if (tmp_len < numblocks * blocksize) {
|
||||
/* possibly we can do with fewer blocks than estimated */
|
||||
numblocks = (tmp_len + blocksize - 1) / blocksize;
|
||||
if (numblocks > pre_comp->numblocks) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
totalnum = num + numblocks;
|
||||
}
|
||||
|
||||
/* split wNAF in 'numblocks' parts */
|
||||
pp = tmp_wNAF;
|
||||
tmp_points = pre_comp->points;
|
||||
|
||||
for (i = num; i < totalnum; i++) {
|
||||
if (i < totalnum - 1) {
|
||||
wNAF_len[i] = blocksize;
|
||||
if (tmp_len < blocksize) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
tmp_len -= blocksize;
|
||||
} else {
|
||||
/* last block gets whatever is left
|
||||
* (this could be more or less than 'blocksize'!) */
|
||||
wNAF_len[i] = tmp_len;
|
||||
}
|
||||
|
||||
wNAF[i + 1] = NULL;
|
||||
wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
|
||||
if (wNAF[i] == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
memcpy(wNAF[i], pp, wNAF_len[i]);
|
||||
if (wNAF_len[i] > max_len) {
|
||||
max_len = wNAF_len[i];
|
||||
}
|
||||
|
||||
if (*tmp_points == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
goto err;
|
||||
}
|
||||
val_sub[i] = tmp_points;
|
||||
tmp_points += pre_points_per_block;
|
||||
pp += blocksize;
|
||||
}
|
||||
OPENSSL_free(tmp_wNAF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All points we precompute now go into a single array 'val'.
|
||||
* 'val_sub[i]' is a pointer to the subarray for the i-th point,
|
||||
* or to a subarray of 'pre_comp->points' if we already have precomputation.
|
||||
*/
|
||||
/* All points we precompute now go into a single array 'val'. 'val_sub[i]' is
|
||||
* a pointer to the subarray for the i-th point. */
|
||||
val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
|
||||
if (val == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
@@ -528,7 +318,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
|
||||
/* allocate points for precomputation */
|
||||
v = val;
|
||||
for (i = 0; i < num + num_scalar; i++) {
|
||||
for (i = 0; i < total_num; i++) {
|
||||
val_sub[i] = v;
|
||||
for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
|
||||
*v = EC_POINT_new(group);
|
||||
@@ -553,7 +343,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
* val_sub[i][2] := 5 * points[i]
|
||||
* ...
|
||||
*/
|
||||
for (i = 0; i < num + num_scalar; i++) {
|
||||
for (i = 0; i < total_num; i++) {
|
||||
if (i < num) {
|
||||
if (!EC_POINT_copy(val_sub[i][0], points[i])) {
|
||||
goto err;
|
||||
@@ -587,7 +377,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < totalnum; i++) {
|
||||
for (i = 0; i < total_num; i++) {
|
||||
if (wNAF_len[i] > (size_t)k) {
|
||||
int digit = wNAF[i][k];
|
||||
int is_neg;
|
||||
@@ -657,192 +447,3 @@ err:
|
||||
OPENSSL_free(val_sub);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ec_wNAF_precompute_mult()
|
||||
* creates an EC_PRE_COMP object with preprecomputed multiples of the generator
|
||||
* for use with wNAF splitting as implemented in ec_wNAF_mul().
|
||||
*
|
||||
* 'pre_comp->points' is an array of multiples of the generator
|
||||
* of the following form:
|
||||
* points[0] = generator;
|
||||
* points[1] = 3 * generator;
|
||||
* ...
|
||||
* points[2^(w-1)-1] = (2^(w-1)-1) * generator;
|
||||
* points[2^(w-1)] = 2^blocksize * generator;
|
||||
* points[2^(w-1)+1] = 3 * 2^blocksize * generator;
|
||||
* ...
|
||||
* points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) *
|
||||
*generator
|
||||
* points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) *
|
||||
*generator
|
||||
* ...
|
||||
* points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) *
|
||||
*generator
|
||||
* points[2^(w-1)*numblocks] = NULL
|
||||
*/
|
||||
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
|
||||
const EC_POINT *generator;
|
||||
EC_POINT *tmp_point = NULL, *base = NULL, **var;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
BIGNUM *order;
|
||||
size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
|
||||
EC_POINT **points = NULL;
|
||||
EC_PRE_COMP *pre_comp;
|
||||
int ret = 0;
|
||||
|
||||
/* if there is an old EC_PRE_COMP object, throw it away */
|
||||
ec_pre_comp_free(group->pre_comp);
|
||||
group->pre_comp = NULL;
|
||||
|
||||
generator = EC_GROUP_get0_generator(group);
|
||||
if (generator == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pre_comp = ec_pre_comp_new();
|
||||
if (pre_comp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
order = BN_CTX_get(ctx);
|
||||
if (order == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_zero(order)) {
|
||||
OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
bits = BN_num_bits(order);
|
||||
/* The following parameters mean we precompute (approximately)
|
||||
* one point per bit.
|
||||
*
|
||||
* TBD: The combination 8, 4 is perfect for 160 bits; for other
|
||||
* bit lengths, other parameter combinations might provide better
|
||||
* efficiency.
|
||||
*/
|
||||
blocksize = 8;
|
||||
w = 4;
|
||||
if (EC_window_bits_for_scalar_size(bits) > w) {
|
||||
/* let's not make the window too small ... */
|
||||
w = EC_window_bits_for_scalar_size(bits);
|
||||
}
|
||||
|
||||
numblocks = (bits + blocksize - 1) /
|
||||
blocksize; /* max. number of blocks to use for wNAF splitting */
|
||||
|
||||
pre_points_per_block = (size_t)1 << (w - 1);
|
||||
num = pre_points_per_block *
|
||||
numblocks; /* number of points to compute and store */
|
||||
|
||||
points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
|
||||
if (!points) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
var = points;
|
||||
var[num] = NULL; /* pivot */
|
||||
for (i = 0; i < num; i++) {
|
||||
if ((var[i] = EC_POINT_new(group)) == NULL) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_copy(base, generator)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* do the precomputation */
|
||||
for (i = 0; i < numblocks; i++) {
|
||||
size_t j;
|
||||
|
||||
if (!EC_POINT_dbl(group, tmp_point, base, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_copy(*var++, base)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (j = 1; j < pre_points_per_block; j++, var++) {
|
||||
/* calculate odd multiples of the current base point */
|
||||
if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < numblocks - 1) {
|
||||
/* get the next base (multiply current one by 2^blocksize) */
|
||||
size_t k;
|
||||
|
||||
if (blocksize <= 2) {
|
||||
OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_POINT_dbl(group, base, tmp_point, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
for (k = 2; k < blocksize; k++) {
|
||||
if (!EC_POINT_dbl(group, base, base, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!EC_POINTs_make_affine(group, num, points, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
pre_comp->blocksize = blocksize;
|
||||
pre_comp->numblocks = numblocks;
|
||||
pre_comp->w = w;
|
||||
pre_comp->points = points;
|
||||
points = NULL;
|
||||
pre_comp->num = num;
|
||||
|
||||
group->pre_comp = pre_comp;
|
||||
pre_comp = NULL;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx != NULL) {
|
||||
BN_CTX_end(ctx);
|
||||
}
|
||||
BN_CTX_free(new_ctx);
|
||||
ec_pre_comp_free(pre_comp);
|
||||
if (points) {
|
||||
EC_POINT **p;
|
||||
|
||||
for (p = points; *p != NULL; p++) {
|
||||
EC_POINT_free(*p);
|
||||
}
|
||||
OPENSSL_free(points);
|
||||
}
|
||||
EC_POINT_free(tmp_point);
|
||||
EC_POINT_free(base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+14
-25
@@ -143,7 +143,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey) {
|
||||
int ret = 0;
|
||||
BN_CTX *ctx;
|
||||
BIGNUM *order, *u1, *u2, *m, *X;
|
||||
BIGNUM *u1, *u2, *m, *X;
|
||||
EC_POINT *point = NULL;
|
||||
const EC_GROUP *group;
|
||||
const EC_POINT *pub_key;
|
||||
@@ -167,21 +167,16 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
|
||||
return 0;
|
||||
}
|
||||
BN_CTX_start(ctx);
|
||||
order = BN_CTX_get(ctx);
|
||||
u1 = BN_CTX_get(ctx);
|
||||
u2 = BN_CTX_get(ctx);
|
||||
m = BN_CTX_get(ctx);
|
||||
X = BN_CTX_get(ctx);
|
||||
if (order == NULL || u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
|
||||
if (u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
const BIGNUM *order = EC_GROUP_get0_order(group);
|
||||
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
|
||||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
|
||||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
|
||||
@@ -229,7 +224,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
|
||||
ret = (BN_ucmp(u1, sig->r) == 0);
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
@@ -239,7 +234,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
BIGNUM **rp, const uint8_t *digest,
|
||||
size_t digest_len) {
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
|
||||
BIGNUM *k = NULL, *r = NULL, *X = NULL;
|
||||
EC_POINT *tmp_point = NULL;
|
||||
const EC_GROUP *group;
|
||||
int ret = 0;
|
||||
@@ -260,9 +255,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
|
||||
k = BN_new(); /* this value is later returned in *kinvp */
|
||||
r = BN_new(); /* this value is later returned in *rp */
|
||||
order = BN_new();
|
||||
X = BN_new();
|
||||
if (!k || !r || !order || !X) {
|
||||
if (k == NULL || r == NULL || X == NULL) {
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
@@ -271,10 +265,8 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
const BIGNUM *order = EC_GROUP_get0_order(group);
|
||||
|
||||
do {
|
||||
/* If possible, we'll include the private key and message digest in the k
|
||||
@@ -360,7 +352,6 @@ err:
|
||||
if (ctx_in == NULL) {
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
BN_free(order);
|
||||
EC_POINT_free(tmp_point);
|
||||
BN_clear_free(X);
|
||||
return ret;
|
||||
@@ -374,7 +365,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r,
|
||||
EC_KEY *eckey) {
|
||||
int ok = 0;
|
||||
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
|
||||
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
|
||||
const BIGNUM *ckinv;
|
||||
BN_CTX *ctx = NULL;
|
||||
const EC_GROUP *group;
|
||||
@@ -401,16 +392,15 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
|
||||
}
|
||||
s = ret->s;
|
||||
|
||||
if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
|
||||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
|
||||
if ((ctx = BN_CTX_new()) == NULL ||
|
||||
(tmp = BN_new()) == NULL ||
|
||||
(m = BN_new()) == NULL) {
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order(group, order, ctx)) {
|
||||
OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
const BIGNUM *order = EC_GROUP_get0_order(group);
|
||||
|
||||
if (!digest_to_bn(m, digest, digest_len, order)) {
|
||||
goto err;
|
||||
}
|
||||
@@ -464,7 +454,6 @@ err:
|
||||
BN_CTX_free(ctx);
|
||||
BN_clear_free(m);
|
||||
BN_clear_free(tmp);
|
||||
BN_free(order);
|
||||
BN_clear_free(kinv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -78,17 +78,7 @@ size_t ECDSA_size(const EC_KEY *key) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIGNUM *order = BN_new();
|
||||
if (order == NULL) {
|
||||
return 0;
|
||||
}
|
||||
if (!EC_GROUP_get_order(group, order, NULL)) {
|
||||
BN_clear_free(order);
|
||||
return 0;
|
||||
}
|
||||
|
||||
group_order_size = BN_num_bytes(order);
|
||||
BN_clear_free(order);
|
||||
group_order_size = BN_num_bytes(EC_GROUP_get0_order(group));
|
||||
}
|
||||
|
||||
return ECDSA_SIG_max_len(group_order_size);
|
||||
|
||||
@@ -176,12 +176,8 @@ static bool TestBuiltin(FILE *out) {
|
||||
fprintf(out, " failed\n");
|
||||
return false;
|
||||
}
|
||||
ScopedBIGNUM order(BN_new());
|
||||
if (!order || !EC_GROUP_get_order(group.get(), order.get(), NULL)) {
|
||||
fprintf(out, " failed\n");
|
||||
return false;
|
||||
}
|
||||
if (BN_num_bits(order.get()) < 160) {
|
||||
const BIGNUM *order = EC_GROUP_get0_order(group.get());
|
||||
if (BN_num_bits(order) < 160) {
|
||||
// Too small to test.
|
||||
fprintf(out, " skipped\n");
|
||||
continue;
|
||||
@@ -261,7 +257,7 @@ static bool TestBuiltin(FILE *out) {
|
||||
signature.data(), signature.size()));
|
||||
if (!ecdsa_sig ||
|
||||
!TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(),
|
||||
eckey.get(), order.get())) {
|
||||
eckey.get(), order)) {
|
||||
fprintf(out, " failed\n");
|
||||
return false;
|
||||
}
|
||||
@@ -300,7 +296,7 @@ static bool TestBuiltin(FILE *out) {
|
||||
fflush(out);
|
||||
// Verify a tampered signature.
|
||||
if (!TestTamperedSig(out, kRawApi, digest, 20, ecdsa_sig.get(), eckey.get(),
|
||||
order.get())) {
|
||||
order)) {
|
||||
fprintf(out, " failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
+141
-179
@@ -7,138 +7,111 @@ SSL,105,BAD_DH_P_LENGTH
|
||||
SSL,106,BAD_DIGEST_LENGTH
|
||||
SSL,107,BAD_ECC_CERT
|
||||
SSL,108,BAD_ECPOINT
|
||||
SSL,109,BAD_HANDSHAKE_LENGTH
|
||||
SSL,110,BAD_HANDSHAKE_RECORD
|
||||
SSL,111,BAD_HELLO_REQUEST
|
||||
SSL,112,BAD_LENGTH
|
||||
SSL,113,BAD_PACKET_LENGTH
|
||||
SSL,114,BAD_RSA_ENCRYPT
|
||||
SSL,115,BAD_SIGNATURE
|
||||
SSL,116,BAD_SRTP_MKI_VALUE
|
||||
SSL,117,BAD_SRTP_PROTECTION_PROFILE_LIST
|
||||
SSL,118,BAD_SSL_FILETYPE
|
||||
SSL,119,BAD_WRITE_RETRY
|
||||
SSL,120,BIO_NOT_SET
|
||||
SSL,121,BN_LIB
|
||||
SSL,272,BUFFER_TOO_SMALL
|
||||
SSL,122,CANNOT_SERIALIZE_PUBLIC_KEY
|
||||
SSL,123,CA_DN_LENGTH_MISMATCH
|
||||
SSL,124,CA_DN_TOO_LONG
|
||||
SSL,125,CCS_RECEIVED_EARLY
|
||||
SSL,126,CERTIFICATE_VERIFY_FAILED
|
||||
SSL,127,CERT_CB_ERROR
|
||||
SSL,128,CERT_LENGTH_MISMATCH
|
||||
SSL,129,CHANNEL_ID_NOT_P256
|
||||
SSL,130,CHANNEL_ID_SIGNATURE_INVALID
|
||||
SSL,131,CIPHER_CODE_WRONG_LENGTH
|
||||
SSL,132,CIPHER_OR_HASH_UNAVAILABLE
|
||||
SSL,133,CLIENTHELLO_PARSE_FAILED
|
||||
SSL,134,CLIENTHELLO_TLSEXT
|
||||
SSL,135,CONNECTION_REJECTED
|
||||
SSL,136,CONNECTION_TYPE_NOT_SET
|
||||
SSL,137,COOKIE_MISMATCH
|
||||
SSL,284,CUSTOM_EXTENSION_CONTENTS_TOO_LARGE
|
||||
SSL,285,CUSTOM_EXTENSION_ERROR
|
||||
SSL,138,D2I_ECDSA_SIG
|
||||
SSL,139,DATA_BETWEEN_CCS_AND_FINISHED
|
||||
SSL,140,DATA_LENGTH_TOO_LONG
|
||||
SSL,141,DECODE_ERROR
|
||||
SSL,142,DECRYPTION_FAILED
|
||||
SSL,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
|
||||
SSL,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
|
||||
SSL,287,DH_P_TOO_LONG
|
||||
SSL,145,DIGEST_CHECK_FAILED
|
||||
SSL,146,DTLS_MESSAGE_TOO_BIG
|
||||
SSL,147,ECC_CERT_NOT_FOR_SIGNING
|
||||
SSL,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
|
||||
SSL,276,EMS_STATE_INCONSISTENT
|
||||
SSL,149,ENCRYPTED_LENGTH_TOO_LONG
|
||||
SSL,281,ERROR_ADDING_EXTENSION
|
||||
SSL,150,ERROR_IN_RECEIVED_CIPHER_LIST
|
||||
SSL,282,ERROR_PARSING_EXTENSION
|
||||
SSL,151,EVP_DIGESTSIGNFINAL_FAILED
|
||||
SSL,152,EVP_DIGESTSIGNINIT_FAILED
|
||||
SSL,153,EXCESSIVE_MESSAGE_SIZE
|
||||
SSL,154,EXTRA_DATA_IN_MESSAGE
|
||||
SSL,271,FRAGMENT_MISMATCH
|
||||
SSL,155,GOT_A_FIN_BEFORE_A_CCS
|
||||
SSL,156,GOT_CHANNEL_ID_BEFORE_A_CCS
|
||||
SSL,157,GOT_NEXT_PROTO_BEFORE_A_CCS
|
||||
SSL,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION
|
||||
SSL,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
|
||||
SSL,160,HANDSHAKE_RECORD_BEFORE_CCS
|
||||
SSL,161,HTTPS_PROXY_REQUEST
|
||||
SSL,162,HTTP_REQUEST
|
||||
SSL,163,INAPPROPRIATE_FALLBACK
|
||||
SSL,164,INVALID_COMMAND
|
||||
SSL,165,INVALID_MESSAGE
|
||||
SSL,166,INVALID_SSL_SESSION
|
||||
SSL,167,INVALID_TICKET_KEYS_LENGTH
|
||||
SSL,168,LENGTH_MISMATCH
|
||||
SSL,169,LIBRARY_HAS_NO_CIPHERS
|
||||
SSL,170,MISSING_DH_KEY
|
||||
SSL,171,MISSING_ECDSA_SIGNING_CERT
|
||||
SSL,283,MISSING_EXTENSION
|
||||
SSL,172,MISSING_RSA_CERTIFICATE
|
||||
SSL,173,MISSING_RSA_ENCRYPTING_CERT
|
||||
SSL,174,MISSING_RSA_SIGNING_CERT
|
||||
SSL,175,MISSING_TMP_DH_KEY
|
||||
SSL,176,MISSING_TMP_ECDH_KEY
|
||||
SSL,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
|
||||
SSL,178,MTU_TOO_SMALL
|
||||
SSL,286,NEGOTIATED_BOTH_NPN_AND_ALPN
|
||||
SSL,179,NESTED_GROUP
|
||||
SSL,180,NO_CERTIFICATES_RETURNED
|
||||
SSL,181,NO_CERTIFICATE_ASSIGNED
|
||||
SSL,182,NO_CERTIFICATE_SET
|
||||
SSL,183,NO_CIPHERS_AVAILABLE
|
||||
SSL,184,NO_CIPHERS_PASSED
|
||||
SSL,185,NO_CIPHERS_SPECIFIED
|
||||
SSL,186,NO_CIPHER_MATCH
|
||||
SSL,187,NO_COMPRESSION_SPECIFIED
|
||||
SSL,188,NO_METHOD_SPECIFIED
|
||||
SSL,189,NO_P256_SUPPORT
|
||||
SSL,190,NO_PRIVATE_KEY_ASSIGNED
|
||||
SSL,191,NO_RENEGOTIATION
|
||||
SSL,192,NO_REQUIRED_DIGEST
|
||||
SSL,193,NO_SHARED_CIPHER
|
||||
SSL,194,NO_SHARED_SIGATURE_ALGORITHMS
|
||||
SSL,195,NO_SRTP_PROFILES
|
||||
SSL,196,NULL_SSL_CTX
|
||||
SSL,197,NULL_SSL_METHOD_PASSED
|
||||
SSL,198,OLD_SESSION_CIPHER_NOT_RETURNED
|
||||
SSL,273,OLD_SESSION_VERSION_NOT_RETURNED
|
||||
SSL,274,OUTPUT_ALIASES_INPUT
|
||||
SSL,199,PACKET_LENGTH_TOO_LONG
|
||||
SSL,200,PARSE_TLSEXT
|
||||
SSL,201,PATH_TOO_LONG
|
||||
SSL,202,PEER_DID_NOT_RETURN_A_CERTIFICATE
|
||||
SSL,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
|
||||
SSL,204,PROTOCOL_IS_SHUTDOWN
|
||||
SSL,205,PSK_IDENTITY_NOT_FOUND
|
||||
SSL,206,PSK_NO_CLIENT_CB
|
||||
SSL,207,PSK_NO_SERVER_CB
|
||||
SSL,208,READ_BIO_NOT_SET
|
||||
SSL,209,READ_TIMEOUT_EXPIRED
|
||||
SSL,210,RECORD_LENGTH_MISMATCH
|
||||
SSL,211,RECORD_TOO_LARGE
|
||||
SSL,212,RENEGOTIATE_EXT_TOO_LONG
|
||||
SSL,213,RENEGOTIATION_ENCODING_ERR
|
||||
SSL,214,RENEGOTIATION_MISMATCH
|
||||
SSL,215,REQUIRED_CIPHER_MISSING
|
||||
SSL,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
|
||||
SSL,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
|
||||
SSL,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
|
||||
SSL,217,SERVERHELLO_TLSEXT
|
||||
SSL,218,SESSION_ID_CONTEXT_UNINITIALIZED
|
||||
SSL,219,SESSION_MAY_NOT_BE_CREATED
|
||||
SSL,220,SIGNATURE_ALGORITHMS_ERROR
|
||||
SSL,280,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
|
||||
SSL,221,SRTP_COULD_NOT_ALLOCATE_PROFILES
|
||||
SSL,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
|
||||
SSL,223,SRTP_UNKNOWN_PROTECTION_PROFILE
|
||||
SSL,224,SSL3_EXT_INVALID_SERVERNAME
|
||||
SSL,225,SSL3_EXT_INVALID_SERVERNAME_TYPE
|
||||
SSL,109,BAD_HANDSHAKE_RECORD
|
||||
SSL,110,BAD_HELLO_REQUEST
|
||||
SSL,111,BAD_LENGTH
|
||||
SSL,112,BAD_PACKET_LENGTH
|
||||
SSL,113,BAD_RSA_ENCRYPT
|
||||
SSL,114,BAD_SIGNATURE
|
||||
SSL,115,BAD_SRTP_MKI_VALUE
|
||||
SSL,116,BAD_SRTP_PROTECTION_PROFILE_LIST
|
||||
SSL,117,BAD_SSL_FILETYPE
|
||||
SSL,118,BAD_WRITE_RETRY
|
||||
SSL,119,BIO_NOT_SET
|
||||
SSL,120,BN_LIB
|
||||
SSL,121,BUFFER_TOO_SMALL
|
||||
SSL,122,CA_DN_LENGTH_MISMATCH
|
||||
SSL,123,CA_DN_TOO_LONG
|
||||
SSL,124,CCS_RECEIVED_EARLY
|
||||
SSL,125,CERTIFICATE_VERIFY_FAILED
|
||||
SSL,126,CERT_CB_ERROR
|
||||
SSL,127,CERT_LENGTH_MISMATCH
|
||||
SSL,128,CHANNEL_ID_NOT_P256
|
||||
SSL,129,CHANNEL_ID_SIGNATURE_INVALID
|
||||
SSL,130,CIPHER_OR_HASH_UNAVAILABLE
|
||||
SSL,131,CLIENTHELLO_PARSE_FAILED
|
||||
SSL,132,CLIENTHELLO_TLSEXT
|
||||
SSL,133,CONNECTION_REJECTED
|
||||
SSL,134,CONNECTION_TYPE_NOT_SET
|
||||
SSL,135,CUSTOM_EXTENSION_ERROR
|
||||
SSL,136,DATA_LENGTH_TOO_LONG
|
||||
SSL,137,DECODE_ERROR
|
||||
SSL,138,DECRYPTION_FAILED
|
||||
SSL,139,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
|
||||
SSL,140,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
|
||||
SSL,141,DH_P_TOO_LONG
|
||||
SSL,142,DIGEST_CHECK_FAILED
|
||||
SSL,143,DTLS_MESSAGE_TOO_BIG
|
||||
SSL,144,ECC_CERT_NOT_FOR_SIGNING
|
||||
SSL,145,EMS_STATE_INCONSISTENT
|
||||
SSL,146,ENCRYPTED_LENGTH_TOO_LONG
|
||||
SSL,147,ERROR_ADDING_EXTENSION
|
||||
SSL,148,ERROR_IN_RECEIVED_CIPHER_LIST
|
||||
SSL,149,ERROR_PARSING_EXTENSION
|
||||
SSL,150,EXCESSIVE_MESSAGE_SIZE
|
||||
SSL,151,EXTRA_DATA_IN_MESSAGE
|
||||
SSL,152,FRAGMENT_MISMATCH
|
||||
SSL,153,GOT_NEXT_PROTO_WITHOUT_EXTENSION
|
||||
SSL,154,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
|
||||
SSL,155,HTTPS_PROXY_REQUEST
|
||||
SSL,156,HTTP_REQUEST
|
||||
SSL,157,INAPPROPRIATE_FALLBACK
|
||||
SSL,158,INVALID_COMMAND
|
||||
SSL,159,INVALID_MESSAGE
|
||||
SSL,160,INVALID_SSL_SESSION
|
||||
SSL,161,INVALID_TICKET_KEYS_LENGTH
|
||||
SSL,162,LENGTH_MISMATCH
|
||||
SSL,163,LIBRARY_HAS_NO_CIPHERS
|
||||
SSL,164,MISSING_EXTENSION
|
||||
SSL,165,MISSING_RSA_CERTIFICATE
|
||||
SSL,166,MISSING_TMP_DH_KEY
|
||||
SSL,167,MISSING_TMP_ECDH_KEY
|
||||
SSL,168,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
|
||||
SSL,169,MTU_TOO_SMALL
|
||||
SSL,170,NEGOTIATED_BOTH_NPN_AND_ALPN
|
||||
SSL,171,NESTED_GROUP
|
||||
SSL,172,NO_CERTIFICATES_RETURNED
|
||||
SSL,173,NO_CERTIFICATE_ASSIGNED
|
||||
SSL,174,NO_CERTIFICATE_SET
|
||||
SSL,175,NO_CIPHERS_AVAILABLE
|
||||
SSL,176,NO_CIPHERS_PASSED
|
||||
SSL,177,NO_CIPHER_MATCH
|
||||
SSL,178,NO_COMPRESSION_SPECIFIED
|
||||
SSL,179,NO_METHOD_SPECIFIED
|
||||
SSL,180,NO_P256_SUPPORT
|
||||
SSL,181,NO_PRIVATE_KEY_ASSIGNED
|
||||
SSL,182,NO_RENEGOTIATION
|
||||
SSL,183,NO_REQUIRED_DIGEST
|
||||
SSL,184,NO_SHARED_CIPHER
|
||||
SSL,185,NULL_SSL_CTX
|
||||
SSL,186,NULL_SSL_METHOD_PASSED
|
||||
SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
|
||||
SSL,188,OLD_SESSION_VERSION_NOT_RETURNED
|
||||
SSL,189,OUTPUT_ALIASES_INPUT
|
||||
SSL,190,PARSE_TLSEXT
|
||||
SSL,191,PATH_TOO_LONG
|
||||
SSL,192,PEER_DID_NOT_RETURN_A_CERTIFICATE
|
||||
SSL,193,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
|
||||
SSL,194,PROTOCOL_IS_SHUTDOWN
|
||||
SSL,195,PSK_IDENTITY_NOT_FOUND
|
||||
SSL,196,PSK_NO_CLIENT_CB
|
||||
SSL,197,PSK_NO_SERVER_CB
|
||||
SSL,198,READ_TIMEOUT_EXPIRED
|
||||
SSL,199,RECORD_LENGTH_MISMATCH
|
||||
SSL,200,RECORD_TOO_LARGE
|
||||
SSL,201,RENEGOTIATION_ENCODING_ERR
|
||||
SSL,202,RENEGOTIATION_MISMATCH
|
||||
SSL,203,REQUIRED_CIPHER_MISSING
|
||||
SSL,204,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
|
||||
SSL,205,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
|
||||
SSL,206,SCSV_RECEIVED_WHEN_RENEGOTIATING
|
||||
SSL,207,SERVERHELLO_TLSEXT
|
||||
SSL,208,SESSION_ID_CONTEXT_UNINITIALIZED
|
||||
SSL,209,SESSION_MAY_NOT_BE_CREATED
|
||||
SSL,210,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
|
||||
SSL,211,SRTP_COULD_NOT_ALLOCATE_PROFILES
|
||||
SSL,212,SRTP_UNKNOWN_PROTECTION_PROFILE
|
||||
SSL,213,SSL3_EXT_INVALID_SERVERNAME
|
||||
SSL,1042,SSLV3_ALERT_BAD_CERTIFICATE
|
||||
SSL,1020,SSLV3_ALERT_BAD_RECORD_MAC
|
||||
SSL,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED
|
||||
@@ -151,12 +124,9 @@ SSL,1047,SSLV3_ALERT_ILLEGAL_PARAMETER
|
||||
SSL,1041,SSLV3_ALERT_NO_CERTIFICATE
|
||||
SSL,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE
|
||||
SSL,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
|
||||
SSL,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
|
||||
SSL,227,SSL_HANDSHAKE_FAILURE
|
||||
SSL,228,SSL_SESSION_ID_CALLBACK_FAILED
|
||||
SSL,229,SSL_SESSION_ID_CONFLICT
|
||||
SSL,230,SSL_SESSION_ID_CONTEXT_TOO_LONG
|
||||
SSL,231,SSL_SESSION_ID_HAS_BAD_LENGTH
|
||||
SSL,214,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
|
||||
SSL,215,SSL_HANDSHAKE_FAILURE
|
||||
SSL,216,SSL_SESSION_ID_CONTEXT_TOO_LONG
|
||||
SSL,1049,TLSV1_ALERT_ACCESS_DENIED
|
||||
SSL,1050,TLSV1_ALERT_DECODE_ERROR
|
||||
SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED
|
||||
@@ -175,44 +145,36 @@ SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
|
||||
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
|
||||
SSL,1112,TLSV1_UNRECOGNIZED_NAME
|
||||
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
|
||||
SSL,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER
|
||||
SSL,233,TLS_ILLEGAL_EXPORTER_LABEL
|
||||
SSL,234,TLS_INVALID_ECPOINTFORMAT_LIST
|
||||
SSL,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
|
||||
SSL,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
|
||||
SSL,237,TOO_MANY_EMPTY_FRAGMENTS
|
||||
SSL,278,TOO_MANY_WARNING_ALERTS
|
||||
SSL,238,UNABLE_TO_FIND_ECDH_PARAMETERS
|
||||
SSL,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS
|
||||
SSL,279,UNEXPECTED_EXTENSION
|
||||
SSL,240,UNEXPECTED_GROUP_CLOSE
|
||||
SSL,241,UNEXPECTED_MESSAGE
|
||||
SSL,242,UNEXPECTED_OPERATOR_IN_GROUP
|
||||
SSL,243,UNEXPECTED_RECORD
|
||||
SSL,244,UNINITIALIZED
|
||||
SSL,245,UNKNOWN_ALERT_TYPE
|
||||
SSL,246,UNKNOWN_CERTIFICATE_TYPE
|
||||
SSL,247,UNKNOWN_CIPHER_RETURNED
|
||||
SSL,248,UNKNOWN_CIPHER_TYPE
|
||||
SSL,249,UNKNOWN_DIGEST
|
||||
SSL,250,UNKNOWN_KEY_EXCHANGE_TYPE
|
||||
SSL,251,UNKNOWN_PROTOCOL
|
||||
SSL,252,UNKNOWN_SSL_VERSION
|
||||
SSL,253,UNKNOWN_STATE
|
||||
SSL,254,UNPROCESSED_HANDSHAKE_DATA
|
||||
SSL,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
|
||||
SSL,256,UNSUPPORTED_CIPHER
|
||||
SSL,257,UNSUPPORTED_COMPRESSION_ALGORITHM
|
||||
SSL,258,UNSUPPORTED_ELLIPTIC_CURVE
|
||||
SSL,259,UNSUPPORTED_PROTOCOL
|
||||
SSL,260,UNSUPPORTED_SSL_VERSION
|
||||
SSL,261,USE_SRTP_NOT_NEGOTIATED
|
||||
SSL,262,WRONG_CERTIFICATE_TYPE
|
||||
SSL,263,WRONG_CIPHER_RETURNED
|
||||
SSL,264,WRONG_CURVE
|
||||
SSL,265,WRONG_MESSAGE_TYPE
|
||||
SSL,266,WRONG_SIGNATURE_TYPE
|
||||
SSL,267,WRONG_SSL_VERSION
|
||||
SSL,268,WRONG_VERSION_NUMBER
|
||||
SSL,269,X509_LIB
|
||||
SSL,270,X509_VERIFICATION_SETUP_PROBLEMS
|
||||
SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
|
||||
SSL,218,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
|
||||
SSL,219,TOO_MANY_EMPTY_FRAGMENTS
|
||||
SSL,220,TOO_MANY_WARNING_ALERTS
|
||||
SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
|
||||
SSL,222,UNEXPECTED_EXTENSION
|
||||
SSL,223,UNEXPECTED_MESSAGE
|
||||
SSL,224,UNEXPECTED_OPERATOR_IN_GROUP
|
||||
SSL,225,UNEXPECTED_RECORD
|
||||
SSL,226,UNINITIALIZED
|
||||
SSL,227,UNKNOWN_ALERT_TYPE
|
||||
SSL,228,UNKNOWN_CERTIFICATE_TYPE
|
||||
SSL,229,UNKNOWN_CIPHER_RETURNED
|
||||
SSL,230,UNKNOWN_CIPHER_TYPE
|
||||
SSL,231,UNKNOWN_DIGEST
|
||||
SSL,232,UNKNOWN_KEY_EXCHANGE_TYPE
|
||||
SSL,233,UNKNOWN_PROTOCOL
|
||||
SSL,234,UNKNOWN_SSL_VERSION
|
||||
SSL,235,UNKNOWN_STATE
|
||||
SSL,236,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
|
||||
SSL,237,UNSUPPORTED_CIPHER
|
||||
SSL,238,UNSUPPORTED_COMPRESSION_ALGORITHM
|
||||
SSL,239,UNSUPPORTED_ELLIPTIC_CURVE
|
||||
SSL,240,UNSUPPORTED_PROTOCOL
|
||||
SSL,241,WRONG_CERTIFICATE_TYPE
|
||||
SSL,242,WRONG_CIPHER_RETURNED
|
||||
SSL,243,WRONG_CURVE
|
||||
SSL,244,WRONG_MESSAGE_TYPE
|
||||
SSL,245,WRONG_SIGNATURE_TYPE
|
||||
SSL,246,WRONG_SSL_VERSION
|
||||
SSL,247,WRONG_VERSION_NUMBER
|
||||
SSL,248,X509_LIB
|
||||
SSL,249,X509_VERIFICATION_SETUP_PROBLEMS
|
||||
|
||||
+24
-29
@@ -60,7 +60,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -73,10 +72,6 @@
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
|
||||
|
||||
EVP_PKEY *EVP_PKEY_new(void) {
|
||||
EVP_PKEY *ret;
|
||||
|
||||
@@ -235,15 +230,22 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
|
||||
return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key);
|
||||
}
|
||||
|
||||
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
|
||||
RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) {
|
||||
if (pkey->type != EVP_PKEY_RSA) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY);
|
||||
return NULL;
|
||||
}
|
||||
RSA_up_ref(pkey->pkey.rsa);
|
||||
return pkey->pkey.rsa;
|
||||
}
|
||||
|
||||
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
|
||||
RSA *rsa = EVP_PKEY_get0_RSA(pkey);
|
||||
if (rsa != NULL) {
|
||||
RSA_up_ref(rsa);
|
||||
}
|
||||
return rsa;
|
||||
}
|
||||
|
||||
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
|
||||
if (EVP_PKEY_assign_DSA(pkey, key)) {
|
||||
DSA_up_ref(key);
|
||||
@@ -256,15 +258,22 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
|
||||
return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key);
|
||||
}
|
||||
|
||||
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
|
||||
DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) {
|
||||
if (pkey->type != EVP_PKEY_DSA) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
|
||||
return NULL;
|
||||
}
|
||||
DSA_up_ref(pkey->pkey.dsa);
|
||||
return pkey->pkey.dsa;
|
||||
}
|
||||
|
||||
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
|
||||
DSA *dsa = EVP_PKEY_get0_DSA(pkey);
|
||||
if (dsa != NULL) {
|
||||
DSA_up_ref(dsa);
|
||||
}
|
||||
return dsa;
|
||||
}
|
||||
|
||||
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
|
||||
if (EVP_PKEY_assign_EC_KEY(pkey, key)) {
|
||||
EC_KEY_up_ref(key);
|
||||
@@ -277,34 +286,20 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
|
||||
return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key);
|
||||
}
|
||||
|
||||
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
|
||||
EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) {
|
||||
if (pkey->type != EVP_PKEY_EC) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY);
|
||||
return NULL;
|
||||
}
|
||||
EC_KEY_up_ref(pkey->pkey.ec);
|
||||
return pkey->pkey.ec;
|
||||
}
|
||||
|
||||
int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) {
|
||||
if (EVP_PKEY_assign_DH(pkey, key)) {
|
||||
DH_up_ref(key);
|
||||
return 1;
|
||||
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
|
||||
EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
|
||||
if (ec_key != NULL) {
|
||||
EC_KEY_up_ref(ec_key);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
|
||||
return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key);
|
||||
}
|
||||
|
||||
DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
|
||||
if (pkey->type != EVP_PKEY_DH) {
|
||||
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY);
|
||||
return NULL;
|
||||
}
|
||||
DH_up_ref(pkey->pkey.dh);
|
||||
return pkey->pkey.dh;
|
||||
return ec_key;
|
||||
}
|
||||
|
||||
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
|
||||
|
||||
@@ -66,9 +66,6 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
extern const EVP_PKEY_METHOD rsa_pkey_meth;
|
||||
extern const EVP_PKEY_METHOD ec_pkey_meth;
|
||||
|
||||
static const EVP_PKEY_METHOD *const evp_methods[] = {
|
||||
&rsa_pkey_meth,
|
||||
&ec_pkey_meth,
|
||||
|
||||
+215
-36
@@ -16,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
@@ -233,6 +234,85 @@ static const uint8_t kExamplePSSCert[] = {
|
||||
0x8c, 0x16,
|
||||
};
|
||||
|
||||
// kBadPSSCert is an example RSA-PSS certificate with bad parameters.
|
||||
static const uint8_t kBadPSSCert[] = {
|
||||
0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x02, 0x3a, 0xa0, 0x03, 0x02, 0x01,
|
||||
0x02, 0x02, 0x09, 0x00, 0xd7, 0x30, 0x64, 0xbc, 0x9f, 0x12, 0xfe, 0xc3,
|
||||
0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
|
||||
0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48,
|
||||
0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09,
|
||||
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06,
|
||||
0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04,
|
||||
0x02, 0x02, 0x00, 0xde, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
|
||||
0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
|
||||
0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, 0x65,
|
||||
0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1e, 0x17,
|
||||
0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, 0x31, 0x36, 0x30, 0x32, 0x33,
|
||||
0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x31, 0x36,
|
||||
0x30, 0x32, 0x33, 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06,
|
||||
0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49,
|
||||
0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63,
|
||||
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82,
|
||||
0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
|
||||
0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xda, 0x33, 0xb5, 0x87,
|
||||
0xa9, 0x50, 0x80, 0x18, 0x02, 0x00, 0xfb, 0x32, 0xf5, 0x29, 0x6b, 0xef,
|
||||
0x01, 0x24, 0xeb, 0x86, 0x5a, 0xbe, 0xd5, 0xe3, 0xdd, 0x3b, 0xbc, 0x2c,
|
||||
0xad, 0x65, 0xf6, 0x2a, 0x26, 0x28, 0x4d, 0x8a, 0xc9, 0x61, 0x39, 0xf1,
|
||||
0x84, 0xb9, 0xe7, 0xd3, 0x0a, 0xc7, 0xa8, 0x0a, 0x6d, 0xef, 0xd9, 0xcb,
|
||||
0x20, 0x11, 0xbb, 0x71, 0xf4, 0xa1, 0xc9, 0x9a, 0x85, 0x1c, 0xe6, 0x3f,
|
||||
0x23, 0x39, 0x58, 0x3c, 0xc5, 0x6d, 0xfa, 0x03, 0xe8, 0xdb, 0xdd, 0xe0,
|
||||
0xc3, 0xde, 0x85, 0x76, 0xce, 0x49, 0x06, 0xc8, 0xe1, 0x8e, 0x4c, 0x86,
|
||||
0x9c, 0xec, 0xab, 0xf4, 0xe5, 0x27, 0xb4, 0x5a, 0xaf, 0xc4, 0x36, 0xd3,
|
||||
0x20, 0x81, 0x54, 0xee, 0x8f, 0x48, 0x77, 0x10, 0xf8, 0x79, 0xd6, 0xaa,
|
||||
0x8d, 0x1b, 0xfe, 0x7d, 0xe8, 0x15, 0x13, 0xe0, 0x7b, 0xf6, 0x90, 0xe4,
|
||||
0xe2, 0xcd, 0x2e, 0x8e, 0xc9, 0x3a, 0x75, 0x42, 0xed, 0x0a, 0x0f, 0x51,
|
||||
0xb2, 0xdd, 0x2e, 0x70, 0x61, 0x68, 0xd7, 0xd9, 0xab, 0xf9, 0xbe, 0xe4,
|
||||
0x75, 0xb7, 0xe7, 0xf2, 0x96, 0x7b, 0xd9, 0x93, 0x43, 0x24, 0xfb, 0x9e,
|
||||
0x55, 0xda, 0xd4, 0x01, 0x6c, 0x3d, 0xa2, 0x59, 0x7a, 0xd5, 0x47, 0x18,
|
||||
0x7e, 0x4e, 0xf9, 0x5d, 0xda, 0xcb, 0x93, 0xa2, 0x65, 0x2f, 0x8d, 0x46,
|
||||
0xad, 0x81, 0xdc, 0xf0, 0xa9, 0x5f, 0x5d, 0xfe, 0x37, 0x80, 0x64, 0x2a,
|
||||
0x41, 0xfa, 0xe9, 0x1e, 0x48, 0x38, 0x22, 0x1d, 0x9c, 0x23, 0xa5, 0xad,
|
||||
0xda, 0x78, 0x45, 0x18, 0x0c, 0xeb, 0x95, 0xca, 0x2b, 0xcc, 0xb9, 0x62,
|
||||
0x40, 0x85, 0x09, 0x44, 0x88, 0x4c, 0xf2, 0x1e, 0x08, 0x80, 0x37, 0xe9,
|
||||
0x06, 0x96, 0x8f, 0x75, 0x54, 0x0b, 0xa9, 0x2d, 0xa9, 0x15, 0xb5, 0xda,
|
||||
0xe5, 0xe4, 0x23, 0xaa, 0x2c, 0x89, 0xc1, 0xa9, 0x36, 0xbc, 0x9f, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03,
|
||||
0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78,
|
||||
0xa0, 0x65, 0x2d, 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6,
|
||||
0xe1, 0x5f, 0x7b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
|
||||
0x30, 0x16, 0x80, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, 0xa0, 0x65, 0x2d,
|
||||
0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, 0xe1, 0x5f, 0x7b,
|
||||
0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
|
||||
0x01, 0xff, 0x30, 0x31, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
|
||||
0x01, 0x01, 0x0a, 0x30, 0x24, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
|
||||
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x0d, 0x30, 0x0b,
|
||||
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0xa2,
|
||||
0x04, 0x02, 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xc1,
|
||||
0xb6, 0x6f, 0x74, 0x94, 0x6c, 0x60, 0x75, 0xd8, 0xdc, 0xe1, 0x7b, 0xbf,
|
||||
0x9d, 0xb5, 0xd7, 0x14, 0x75, 0x6c, 0xdb, 0x35, 0x5c, 0x1e, 0xff, 0xe6,
|
||||
0xa8, 0xe6, 0x68, 0x42, 0x41, 0x81, 0xf6, 0xbf, 0xc1, 0x56, 0x02, 0xdb,
|
||||
0xc6, 0x11, 0xeb, 0x15, 0x9d, 0xa9, 0x1c, 0x61, 0x25, 0x6d, 0x46, 0x0f,
|
||||
0x7e, 0x27, 0xdd, 0x4b, 0xdc, 0xed, 0x07, 0xbd, 0xde, 0xd5, 0xde, 0x09,
|
||||
0xf8, 0xfd, 0xbd, 0xa3, 0x4c, 0x81, 0xa9, 0xf7, 0x78, 0xff, 0x01, 0x80,
|
||||
0x73, 0xf2, 0x40, 0xf2, 0xa8, 0x27, 0xe8, 0x00, 0x04, 0x3b, 0xf5, 0xe7,
|
||||
0xa6, 0x58, 0x45, 0x79, 0x34, 0x49, 0x42, 0xd2, 0xd9, 0x56, 0x5e, 0xf9,
|
||||
0x0a, 0x41, 0xd7, 0x81, 0x41, 0x94, 0x77, 0x78, 0x7e, 0x00, 0x3b, 0xca,
|
||||
0xb5, 0xc0, 0x6e, 0x5b, 0xd7, 0x52, 0x52, 0x77, 0x1a, 0x52, 0xb8, 0x0d,
|
||||
0x29, 0x1f, 0x2e, 0xfe, 0x1f, 0xf6, 0xb0, 0xc1, 0xb7, 0xf1, 0x15, 0x98,
|
||||
0x0f, 0x30, 0x5d, 0x74, 0x2f, 0xfa, 0xe9, 0x84, 0xda, 0xde, 0xbe, 0xca,
|
||||
0x91, 0x55, 0x1f, 0x5b, 0xbc, 0xaa, 0x45, 0x07, 0xc4, 0x2e, 0x21, 0x8a,
|
||||
0x75, 0xc9, 0xbe, 0x6e, 0x39, 0x53, 0x10, 0xcb, 0x2f, 0x4b, 0xe1, 0x21,
|
||||
0x1e, 0xea, 0x7d, 0x0b, 0x36, 0xe9, 0xa0, 0x2c, 0x76, 0x17, 0x1f, 0x69,
|
||||
0x34, 0xfb, 0x45, 0x63, 0x7c, 0x84, 0x39, 0xb4, 0x21, 0x98, 0xbd, 0x49,
|
||||
0xca, 0x80, 0x91, 0x5a, 0xa0, 0x44, 0xef, 0x91, 0xb3, 0x14, 0xf6, 0xd1,
|
||||
0x6a, 0x2b, 0xb1, 0xe5, 0x4a, 0x44, 0x92, 0x7b, 0x3e, 0x8b, 0x7b, 0x6b,
|
||||
0x90, 0x6b, 0x2c, 0x67, 0x3b, 0x0e, 0xb9, 0x5a, 0x87, 0x35, 0x33, 0x59,
|
||||
0x94, 0x2f, 0x7e, 0xf6, 0x13, 0xc7, 0x22, 0x87, 0x3d, 0x50, 0xc9, 0x80,
|
||||
0x40, 0xda, 0x35, 0xbc, 0x62, 0x16, 0xdc, 0xd5, 0x95, 0xa1, 0xe1, 0x9b,
|
||||
0x68, 0x9f,
|
||||
};
|
||||
|
||||
// kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
|
||||
// PrivateKeyInfo.
|
||||
static const uint8_t kExampleRSAKeyPKCS8[] = {
|
||||
@@ -342,6 +422,22 @@ static const uint8_t kExampleBadECKeyDER2[] = {
|
||||
0x07,
|
||||
};
|
||||
|
||||
// kInvalidPrivateKey is an invalid private key. See
|
||||
// https://rt.openssl.org/Ticket/Display.html?id=4131.
|
||||
static const uint8_t kInvalidPrivateKey[] = {
|
||||
0x30, 0x39, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x01, 0x38, 0x08,
|
||||
0x04, 0x69, 0x30, 0x30, 0x80, 0x30, 0x19, 0x01, 0x02, 0x9f, 0xf8,
|
||||
0x8b, 0x29, 0x80, 0x30, 0xb0, 0x1b, 0x06, 0x09, 0x22, 0xbe, 0x08,
|
||||
0x04, 0xe9, 0x30, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x3a, 0x01, 0x80,
|
||||
0x09, 0x30, 0x80, 0x06, 0x01, 0x02, 0x30, 0x80, 0x30, 0x01, 0x3b,
|
||||
0x02, 0x00, 0x00, 0x04, 0x20, 0x30, 0x82, 0x04, 0xe9, 0x30, 0xc3,
|
||||
0xe8, 0x30, 0x01, 0x05, 0x30, 0x80, 0x30, 0x01, 0x3b, 0x01, 0x04,
|
||||
0x02, 0x02, 0xff, 0x00, 0x30, 0x29, 0x02, 0x11, 0x03, 0x29, 0x29,
|
||||
0x02, 0x00, 0x99, 0x30, 0x80, 0x06, 0x21, 0x02, 0x24, 0x04, 0xe8,
|
||||
0x30, 0x01, 0x01, 0x04, 0x30, 0x80, 0x1b, 0x06, 0x09, 0x2a, 0x86,
|
||||
0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
|
||||
};
|
||||
|
||||
static ScopedEVP_PKEY LoadExampleRSAKey() {
|
||||
ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
|
||||
sizeof(kExampleRSAKeyDER)));
|
||||
@@ -477,16 +573,52 @@ static bool TestEVP_DigestSignAlgorithm(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
|
||||
CBS cert, cert_body, tbs_cert, algorithm, signature;
|
||||
CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert));
|
||||
if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) ||
|
||||
CBS_len(&cert) != 0 ||
|
||||
static bool ParseCertificate(CBS *out_tbs_cert,
|
||||
ScopedEVP_PKEY *out_pubkey,
|
||||
ScopedX509_ALGOR *out_algor,
|
||||
CBS *out_signature,
|
||||
const CBS *in_) {
|
||||
CBS in = *in_;
|
||||
CBS cert_body, tbs_cert, algorithm, signature;
|
||||
if (!CBS_get_asn1(&in, &cert_body, CBS_ASN1_SEQUENCE) ||
|
||||
CBS_len(&in) != 0 ||
|
||||
!CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) ||
|
||||
!CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) ||
|
||||
CBS_len(&cert_body) != 0) {
|
||||
fprintf(stderr, "Failed to parse certificate\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
CBS tbs_cert_copy = tbs_cert;
|
||||
CBS tbs_cert_body, discard, spki;
|
||||
if (!CBS_get_asn1(&tbs_cert_copy, &tbs_cert_body, CBS_ASN1_SEQUENCE) ||
|
||||
CBS_len(&tbs_cert_copy) != 0 ||
|
||||
!CBS_get_optional_asn1(
|
||||
&tbs_cert_body, &discard, NULL,
|
||||
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
|
||||
!CBS_get_asn1(&tbs_cert_body, &discard /* serialNumber */,
|
||||
CBS_ASN1_INTEGER) ||
|
||||
!CBS_get_asn1(&tbs_cert_body, &discard /* signature */,
|
||||
CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_any_asn1_element(&tbs_cert_body, &discard /* issuer */,
|
||||
NULL, NULL) ||
|
||||
!CBS_get_asn1(&tbs_cert_body, &discard /* validity */,
|
||||
CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_any_asn1_element(&tbs_cert_body, &discard /* subject */,
|
||||
NULL, NULL) ||
|
||||
!CBS_get_asn1_element(&tbs_cert_body, &spki, CBS_ASN1_SEQUENCE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *derp = CBS_data(&spki);
|
||||
ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &derp, CBS_len(&spki)));
|
||||
if (!pubkey || derp != CBS_data(&spki) + CBS_len(&spki)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
derp = CBS_data(&algorithm);
|
||||
ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
|
||||
if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -494,21 +626,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
|
||||
// leading phase byte is just a zero.
|
||||
uint8_t padding;
|
||||
if (!CBS_get_u8(&signature, &padding) || padding != 0) {
|
||||
fprintf(stderr, "Invalid signature padding\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *derp = CBS_data(&algorithm);
|
||||
ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
|
||||
if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
|
||||
fprintf(stderr, "Failed to parse algorithm\n");
|
||||
*out_tbs_cert = tbs_cert;
|
||||
*out_pubkey = std::move(pubkey);
|
||||
*out_algor = std::move(algor);
|
||||
*out_signature = signature;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
|
||||
CBS in, tbs_cert, signature;
|
||||
ScopedEVP_PKEY pkey;
|
||||
ScopedX509_ALGOR algor;
|
||||
CBS_init(&in, kExamplePSSCert, sizeof(kExamplePSSCert));
|
||||
if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
|
||||
fprintf(stderr, "Failed to parse certificate\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedEVP_PKEY pkey = LoadExampleRSAKey();
|
||||
ScopedEVP_MD_CTX md_ctx;
|
||||
if (!pkey ||
|
||||
!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
|
||||
if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
|
||||
pkey.get()) ||
|
||||
!EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
|
||||
CBS_len(&tbs_cert)) ||
|
||||
@@ -519,8 +658,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
|
||||
int expected_id) {
|
||||
static bool TestBadPSSParameters(void) {
|
||||
CBS in, tbs_cert, signature;
|
||||
ScopedEVP_PKEY pkey;
|
||||
ScopedX509_ALGOR algor;
|
||||
CBS_init(&in, kBadPSSCert, sizeof(kBadPSSCert));
|
||||
if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
|
||||
fprintf(stderr, "Failed to parse certificate\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopedEVP_MD_CTX md_ctx;
|
||||
if (EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
|
||||
pkey.get())) {
|
||||
fprintf(stderr, "Unexpectedly processed bad signature parameters\n");
|
||||
return false;
|
||||
}
|
||||
ERR_clear_error();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TestValidPrivateKey(const uint8_t *input, size_t input_len,
|
||||
int expected_id) {
|
||||
const uint8_t *p = input;
|
||||
ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
|
||||
if (!pkey || p != input + input_len) {
|
||||
@@ -536,6 +695,42 @@ static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Testd2i_AutoPrivateKey() {
|
||||
if (!TestValidPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
|
||||
EVP_PKEY_RSA)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TestValidPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
|
||||
EVP_PKEY_RSA)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TestValidPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
|
||||
EVP_PKEY_EC)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
|
||||
EVP_PKEY_DSA)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t *p = kInvalidPrivateKey;
|
||||
ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
|
||||
if (pkey) {
|
||||
fprintf(stderr, "Parsed invalid private key\n");
|
||||
return false;
|
||||
}
|
||||
ERR_clear_error();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
|
||||
static bool TestEVP_PKCS82PKEY(void) {
|
||||
const uint8_t *derp = kExampleBadECKeyDER;
|
||||
@@ -641,30 +836,14 @@ int main(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
|
||||
EVP_PKEY_RSA)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
|
||||
if (!TestBadPSSParameters()) {
|
||||
fprintf(stderr, "TestBadPSSParameters failed\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
|
||||
EVP_PKEY_RSA)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
|
||||
EVP_PKEY_EC)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
|
||||
EVP_PKEY_DSA)) {
|
||||
fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
|
||||
if (!Testd2i_AutoPrivateKey()) {
|
||||
fprintf(stderr, "Testd2i_AutoPrivateKey failed\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -263,6 +263,13 @@ struct evp_pkey_method_st {
|
||||
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
|
||||
} /* EVP_PKEY_METHOD */;
|
||||
|
||||
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
|
||||
|
||||
extern const EVP_PKEY_METHOD rsa_pkey_meth;
|
||||
extern const EVP_PKEY_METHOD ec_pkey_meth;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
|
||||
+5
-19
@@ -337,23 +337,12 @@ static int int_ec_size(const EVP_PKEY *pkey) {
|
||||
}
|
||||
|
||||
static int ec_bits(const EVP_PKEY *pkey) {
|
||||
BIGNUM *order = BN_new();
|
||||
const EC_GROUP *group;
|
||||
int ret;
|
||||
|
||||
if (!order) {
|
||||
const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec);
|
||||
if (group == NULL) {
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
group = EC_KEY_get0_group(pkey->pkey.ec);
|
||||
if (!EC_GROUP_get_order(group, order, NULL)) {
|
||||
ERR_clear_error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = BN_num_bits(order);
|
||||
BN_free(order);
|
||||
return ret;
|
||||
return BN_num_bits(EC_GROUP_get0_order(group));
|
||||
}
|
||||
|
||||
static int ec_missing_parameters(const EVP_PKEY *pkey) {
|
||||
@@ -387,7 +376,6 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
|
||||
const char *ecstr;
|
||||
size_t buf_len = 0, i;
|
||||
int ret = 0, reason = ERR_R_BIO_LIB;
|
||||
BIGNUM *order = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
const EC_GROUP *group;
|
||||
const EC_POINT *public_key;
|
||||
@@ -458,9 +446,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
|
||||
if (!BIO_indent(bp, off, 128)) {
|
||||
goto err;
|
||||
}
|
||||
order = BN_new();
|
||||
if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
|
||||
BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
|
||||
const BIGNUM *order = EC_GROUP_get0_order(group);
|
||||
if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -482,7 +469,6 @@ err:
|
||||
OPENSSL_PUT_ERROR(EVP, reason);
|
||||
}
|
||||
OPENSSL_free(pub_key_bytes);
|
||||
BN_free(order);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_free(buffer);
|
||||
return ret;
|
||||
|
||||
@@ -303,7 +303,7 @@ static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
|
||||
const uint8_t *p;
|
||||
int plen;
|
||||
|
||||
if (alg == NULL ||
|
||||
if (alg == NULL || alg->parameter == NULL ||
|
||||
OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
|
||||
alg->parameter->type != V_ASN1_SEQUENCE) {
|
||||
return NULL;
|
||||
|
||||
+14
-34
@@ -124,14 +124,12 @@
|
||||
struct crypto_ex_data_func_st {
|
||||
long argl; /* Arbitary long */
|
||||
void *argp; /* Arbitary void pointer */
|
||||
CRYPTO_EX_new *new_func;
|
||||
CRYPTO_EX_free *free_func;
|
||||
CRYPTO_EX_dup *dup_func;
|
||||
};
|
||||
|
||||
int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
|
||||
long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
CRYPTO_EX_dup *dup_func,
|
||||
long argl, void *argp, CRYPTO_EX_dup *dup_func,
|
||||
CRYPTO_EX_free *free_func) {
|
||||
CRYPTO_EX_DATA_FUNCS *funcs;
|
||||
int ret = 0;
|
||||
@@ -144,7 +142,6 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
|
||||
|
||||
funcs->argl = argl;
|
||||
funcs->argp = argp;
|
||||
funcs->new_func = new_func;
|
||||
funcs->dup_func = dup_func;
|
||||
funcs->free_func = free_func;
|
||||
|
||||
@@ -230,46 +227,24 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
|
||||
CRYPTO_EX_DATA *ad) {
|
||||
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
|
||||
size_t i;
|
||||
|
||||
void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) {
|
||||
ad->sk = NULL;
|
||||
|
||||
if (!get_func_pointers(&func_pointers, ex_data_class)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
|
||||
CRYPTO_EX_DATA_FUNCS *func_pointer =
|
||||
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
|
||||
if (func_pointer->new_func) {
|
||||
func_pointer->new_func(obj, NULL, ad, i + ex_data_class->num_reserved,
|
||||
func_pointer->argl, func_pointer->argp);
|
||||
}
|
||||
}
|
||||
|
||||
sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
|
||||
const CRYPTO_EX_DATA *from) {
|
||||
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
|
||||
size_t i;
|
||||
|
||||
if (!from->sk) {
|
||||
if (from->sk == NULL) {
|
||||
/* In this case, |from| is blank, which is also the initial state of |to|,
|
||||
* so there's nothing to do. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
|
||||
if (!get_func_pointers(&func_pointers, ex_data_class)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
|
||||
CRYPTO_EX_DATA_FUNCS *func_pointer =
|
||||
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
|
||||
@@ -288,13 +263,18 @@ int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
|
||||
|
||||
void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
|
||||
CRYPTO_EX_DATA *ad) {
|
||||
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
|
||||
size_t i;
|
||||
|
||||
if (!get_func_pointers(&func_pointers, ex_data_class)) {
|
||||
if (ad->sk == NULL) {
|
||||
/* Nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers;
|
||||
if (!get_func_pointers(&func_pointers, ex_data_class)) {
|
||||
/* TODO(davidben): This leaks memory on malloc error. */
|
||||
return;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
|
||||
CRYPTO_EX_DATA_FUNCS *func_pointer =
|
||||
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/* 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 header is linked to under the names of several headers that have been
|
||||
* removed. It's possible to put a #error in here in order to catch that an
|
||||
* clean up older code. */
|
||||
+3
-19
@@ -168,18 +168,6 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define OPENSSL_U64(x) x##UI64
|
||||
#else
|
||||
|
||||
#if defined(OPENSSL_64_BIT)
|
||||
#define OPENSSL_U64(x) x##UL
|
||||
#else
|
||||
#define OPENSSL_U64(x) x##ULL
|
||||
#endif
|
||||
|
||||
#endif /* defined(_MSC_VER) */
|
||||
|
||||
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
|
||||
defined(OPENSSL_AARCH64)
|
||||
/* OPENSSL_cpuid_setup initializes OPENSSL_ia32cap_P. */
|
||||
@@ -509,8 +497,7 @@ typedef struct {
|
||||
* zero otherwise. */
|
||||
OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class,
|
||||
int *out_index, long argl,
|
||||
void *argp, CRYPTO_EX_new *new_func,
|
||||
CRYPTO_EX_dup *dup_func,
|
||||
void *argp, CRYPTO_EX_dup *dup_func,
|
||||
CRYPTO_EX_free *free_func);
|
||||
|
||||
/* CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class
|
||||
@@ -522,11 +509,8 @@ OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val);
|
||||
* function. */
|
||||
OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index);
|
||||
|
||||
/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA| which is
|
||||
* embedded inside of |obj| which is of class |ex_data_class|. Returns one on
|
||||
* success and zero otherwise. */
|
||||
OPENSSL_EXPORT int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
|
||||
void *obj, CRYPTO_EX_DATA *ad);
|
||||
/* CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. */
|
||||
OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad);
|
||||
|
||||
/* CRYPTO_dup_ex_data duplicates |from| into a freshly allocated
|
||||
* |CRYPTO_EX_DATA|, |to|. Both of which are inside objects of the given
|
||||
|
||||
+6
-4
@@ -84,13 +84,13 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
ll = (c)->h[0]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
#define HASH_BLOCK_DATA_ORDER md4_block_data_order
|
||||
|
||||
@@ -103,6 +103,8 @@ void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
#define G(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
|
||||
#define H(b, c, d) ((b) ^ (c) ^ (d))
|
||||
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
|
||||
#define R0(a, b, c, d, k, s, t) \
|
||||
{ \
|
||||
a += ((k) + (t)+F((b), (c), (d))); \
|
||||
|
||||
+6
-4
@@ -106,13 +106,13 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
ll = (c)->h[0]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
#define HASH_BLOCK_DATA_ORDER md5_block_data_order
|
||||
|
||||
@@ -127,6 +127,8 @@ void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num);
|
||||
#define H(b,c,d) ((b) ^ (c) ^ (d))
|
||||
#define I(b,c,d) (((~(d)) | (b)) ^ (c))
|
||||
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
|
||||
#define R0(a,b,c,d,k,s,t) { \
|
||||
a+=((k)+(t)+F((b),(c),(d))); \
|
||||
a=ROTATE(a,s); \
|
||||
|
||||
@@ -140,7 +140,7 @@ $code=<<___;
|
||||
.text
|
||||
.code 32
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef __clang__
|
||||
#define ldrplb ldrbpl
|
||||
#define ldrneb ldrbne
|
||||
#endif
|
||||
|
||||
+6
-7
@@ -55,7 +55,6 @@
|
||||
#include <openssl/cpu.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
@@ -76,7 +75,7 @@
|
||||
#define REDUCE1BIT(V) \
|
||||
do { \
|
||||
if (sizeof(size_t) == 8) { \
|
||||
uint64_t T = OPENSSL_U64(0xe100000000000000) & (0 - (V.lo & 1)); \
|
||||
uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V.lo & 1)); \
|
||||
V.lo = (V.hi << 63) | (V.lo >> 1); \
|
||||
V.hi = (V.hi >> 1) ^ T; \
|
||||
} else { \
|
||||
@@ -586,7 +585,7 @@ int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) {
|
||||
}
|
||||
|
||||
alen += len;
|
||||
if (alen > (OPENSSL_U64(1) << 61) || (sizeof(len) == 8 && alen < len)) {
|
||||
if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) {
|
||||
return 0;
|
||||
}
|
||||
ctx->len.u[0] = alen;
|
||||
@@ -653,7 +652,7 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key,
|
||||
#endif
|
||||
|
||||
mlen += len;
|
||||
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
|
||||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
|
||||
(sizeof(len) == 8 && mlen < len)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -813,7 +812,7 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key,
|
||||
#endif
|
||||
|
||||
mlen += len;
|
||||
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
|
||||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
|
||||
(sizeof(len) == 8 && mlen < len)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -978,7 +977,7 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
|
||||
#endif
|
||||
|
||||
mlen += len;
|
||||
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
|
||||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
|
||||
(sizeof(len) == 8 && mlen < len)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1087,7 +1086,7 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key,
|
||||
#endif
|
||||
|
||||
mlen += len;
|
||||
if (mlen > ((OPENSSL_U64(1) << 36) - 32) ||
|
||||
if (mlen > ((UINT64_C(1) << 36) - 32) ||
|
||||
(sizeof(len) == 8 && mlen < len)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+14
-4
@@ -773,13 +773,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) {
|
||||
if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data ||
|
||||
CBS_len(&ai) > LONG_MAX) {
|
||||
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
|
||||
goto err;
|
||||
}
|
||||
|
||||
inp = CBS_data(&ai);
|
||||
algor = d2i_X509_ALGOR(NULL, &inp, CBS_len(&ai));
|
||||
algor = d2i_X509_ALGOR(NULL, &inp, (long)CBS_len(&ai));
|
||||
if (algor == NULL) {
|
||||
goto err;
|
||||
}
|
||||
@@ -822,9 +823,14 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (CBS_len(&wrapped_contents) > LONG_MAX) {
|
||||
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* encrypted isn't actually an X.509 signature, but it has the same
|
||||
* structure as one and so |X509_SIG| is reused to store it. */
|
||||
encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents));
|
||||
encrypted = d2i_X509_SIG(NULL, &inp, (long)CBS_len(&wrapped_contents));
|
||||
if (encrypted == NULL) {
|
||||
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
|
||||
goto err;
|
||||
@@ -861,8 +867,12 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
|
||||
}
|
||||
|
||||
if (OBJ_cbs2nid(&cert_type) == NID_x509Certificate) {
|
||||
if (CBS_len(&cert) > LONG_MAX) {
|
||||
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
|
||||
goto err;
|
||||
}
|
||||
const uint8_t *inp = CBS_data(&cert);
|
||||
X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
|
||||
X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
|
||||
if (!x509) {
|
||||
OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
|
||||
goto err;
|
||||
|
||||
+6
-1
@@ -192,7 +192,12 @@ int RAND_pseudo_bytes(uint8_t *buf, size_t len) {
|
||||
return RAND_bytes(buf, len);
|
||||
}
|
||||
|
||||
void RAND_seed(const void *buf, int num) {}
|
||||
void RAND_seed(const void *buf, int num) {
|
||||
/* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed
|
||||
* file descriptors etc will be opened. */
|
||||
uint8_t unused;
|
||||
RAND_bytes(&unused, sizeof(unused));
|
||||
}
|
||||
|
||||
int RAND_load_file(const char *path, long num) {
|
||||
if (num < 0) { /* read the "whole file" */
|
||||
|
||||
@@ -83,11 +83,15 @@ static void init_once(void) {
|
||||
|
||||
int flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1) {
|
||||
abort();
|
||||
}
|
||||
flags |= FD_CLOEXEC;
|
||||
if (fcntl(fd, F_SETFD, flags) == -1) {
|
||||
abort();
|
||||
/* Native Client doesn't implement |fcntl|. */
|
||||
if (errno != ENOSYS) {
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
flags |= FD_CLOEXEC;
|
||||
if (fcntl(fd, F_SETFD, flags) == -1) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
urandom_fd = fd;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ if (${ARCH} STREQUAL "x86_64")
|
||||
RC4_ARCH_SOURCES
|
||||
|
||||
rc4-x86_64.${ASM_EXT}
|
||||
rc4-md5-x86_64.${ASM_EXT}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -27,5 +26,4 @@ add_library(
|
||||
)
|
||||
|
||||
perlasm(rc4-x86_64.${ASM_EXT} asm/rc4-x86_64.pl)
|
||||
perlasm(rc4-md5-x86_64.${ASM_EXT} asm/rc4-md5-x86_64.pl)
|
||||
perlasm(rc4-586.${ASM_EXT} asm/rc4-586.pl)
|
||||
|
||||
@@ -1,632 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# ====================================================================
|
||||
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
|
||||
# project. The module is, however, dual licensed under OpenSSL and
|
||||
# CRYPTOGAMS licenses depending on where you obtain it. For further
|
||||
# details see http://www.openssl.org/~appro/cryptogams/.
|
||||
# ====================================================================
|
||||
|
||||
# June 2011
|
||||
#
|
||||
# This is RC4+MD5 "stitch" implementation. The idea, as spelled in
|
||||
# http://download.intel.com/design/intarch/papers/323686.pdf, is that
|
||||
# since both algorithms exhibit instruction-level parallelism, ILP,
|
||||
# below theoretical maximum, interleaving them would allow to utilize
|
||||
# processor resources better and achieve better performance. RC4
|
||||
# instruction sequence is virtually identical to rc4-x86_64.pl, which
|
||||
# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin
|
||||
# and Jim Guilford of Intel. MD5 is fresh implementation aiming to
|
||||
# minimize register usage, which was used as "main thread" with RC4
|
||||
# weaved into it, one RC4 round per one MD5 round. In addition to the
|
||||
# stiched subroutine the script can generate standalone replacement
|
||||
# md5_block_asm_data_order and RC4. Below are performance numbers in
|
||||
# cycles per processed byte, less is better, for these the standalone
|
||||
# subroutines, sum of them, and stitched one:
|
||||
#
|
||||
# RC4 MD5 RC4+MD5 stitch gain
|
||||
# Opteron 6.5(*) 5.4 11.9 7.0 +70%(*)
|
||||
# Core2 6.5 5.8 12.3 7.7 +60%
|
||||
# Westmere 4.3 5.2 9.5 7.0 +36%
|
||||
# Sandy Bridge 4.2 5.5 9.7 6.8 +43%
|
||||
# Atom 9.3 6.5 15.8 11.1 +42%
|
||||
#
|
||||
# (*) rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement
|
||||
# is +53%...
|
||||
|
||||
my ($rc4,$md5)=(1,1); # what to generate?
|
||||
my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(),
|
||||
# but its result is discarded. Idea here is
|
||||
# to be able to use 'openssl speed rc4' for
|
||||
# benchmarking the stitched subroutine...
|
||||
|
||||
my $flavour = shift;
|
||||
my $output = shift;
|
||||
if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
|
||||
|
||||
my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
|
||||
|
||||
$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
|
||||
( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
|
||||
( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
|
||||
die "can't locate x86_64-xlate.pl";
|
||||
|
||||
open OUT,"| \"$^X\" $xlate $flavour $output";
|
||||
*STDOUT=*OUT;
|
||||
|
||||
my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
|
||||
|
||||
if ($rc4 && !$md5) {
|
||||
($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx");
|
||||
$func="RC4"; $nargs=4;
|
||||
} elsif ($md5 && !$rc4) {
|
||||
($ctx,$inp,$len) = ("%rdi","%rsi","%rdx");
|
||||
$func="md5_block_asm_data_order"; $nargs=3;
|
||||
} else {
|
||||
($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9");
|
||||
$func="rc4_md5_enc"; $nargs=6;
|
||||
# void rc4_md5_enc(
|
||||
# RC4_KEY *key, #
|
||||
# const void *in0, # RC4 input
|
||||
# void *out, # RC4 output
|
||||
# MD5_CTX *ctx, #
|
||||
# const void *inp, # MD5 input
|
||||
# size_t len); # number of 64-byte blocks
|
||||
}
|
||||
|
||||
my @K=( 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
|
||||
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
|
||||
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
|
||||
0x6b901122,0xfd987193,0xa679438e,0x49b40821,
|
||||
|
||||
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
|
||||
0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
|
||||
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
|
||||
0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
|
||||
|
||||
0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
|
||||
0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
|
||||
0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
|
||||
0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
|
||||
|
||||
0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
|
||||
0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
|
||||
0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
|
||||
0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 );
|
||||
|
||||
my @V=("%r8d","%r9d","%r10d","%r11d"); # MD5 registers
|
||||
my $tmp="%r12d";
|
||||
|
||||
my @XX=("%rbp","%rsi"); # RC4 registers
|
||||
my @TX=("%rax","%rbx");
|
||||
my $YY="%rcx";
|
||||
my $TY="%rdx";
|
||||
|
||||
my $MOD=32; # 16, 32 or 64
|
||||
|
||||
$code.=<<___;
|
||||
.text
|
||||
.align 16
|
||||
|
||||
.globl $func
|
||||
.type $func,\@function,$nargs
|
||||
$func:
|
||||
cmp \$0,$len
|
||||
je .Labort
|
||||
push %rbx
|
||||
push %rbp
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
sub \$40,%rsp
|
||||
.Lbody:
|
||||
___
|
||||
if ($rc4) {
|
||||
$code.=<<___;
|
||||
$D#md5# mov $ctx,%r11 # reassign arguments
|
||||
mov $len,%r12
|
||||
mov $in0,%r13
|
||||
mov $out,%r14
|
||||
$D#md5# mov $inp,%r15
|
||||
___
|
||||
$ctx="%r11" if ($md5); # reassign arguments
|
||||
$len="%r12";
|
||||
$in0="%r13";
|
||||
$out="%r14";
|
||||
$inp="%r15" if ($md5);
|
||||
$inp=$in0 if (!$md5);
|
||||
$code.=<<___;
|
||||
xor $XX[0],$XX[0]
|
||||
xor $YY,$YY
|
||||
|
||||
lea 8($dat),$dat
|
||||
mov -8($dat),$XX[0]#b
|
||||
mov -4($dat),$YY#b
|
||||
|
||||
inc $XX[0]#b
|
||||
sub $in0,$out
|
||||
movl ($dat,$XX[0],4),$TX[0]#d
|
||||
___
|
||||
$code.=<<___ if (!$md5);
|
||||
xor $TX[1],$TX[1]
|
||||
test \$-128,$len
|
||||
jz .Loop1
|
||||
sub $XX[0],$TX[1]
|
||||
and \$`$MOD-1`,$TX[1]
|
||||
jz .Loop${MOD}_is_hot
|
||||
sub $TX[1],$len
|
||||
.Loop${MOD}_warmup:
|
||||
add $TX[0]#b,$YY#b
|
||||
movl ($dat,$YY,4),$TY#d
|
||||
movl $TX[0]#d,($dat,$YY,4)
|
||||
movl $TY#d,($dat,$XX[0],4)
|
||||
add $TY#b,$TX[0]#b
|
||||
inc $XX[0]#b
|
||||
movl ($dat,$TX[0],4),$TY#d
|
||||
movl ($dat,$XX[0],4),$TX[0]#d
|
||||
xorb ($in0),$TY#b
|
||||
movb $TY#b,($out,$in0)
|
||||
lea 1($in0),$in0
|
||||
dec $TX[1]
|
||||
jnz .Loop${MOD}_warmup
|
||||
|
||||
mov $YY,$TX[1]
|
||||
xor $YY,$YY
|
||||
mov $TX[1]#b,$YY#b
|
||||
|
||||
.Loop${MOD}_is_hot:
|
||||
mov $len,32(%rsp) # save original $len
|
||||
shr \$6,$len # number of 64-byte blocks
|
||||
___
|
||||
if ($D && !$md5) { # stitch in dummy MD5
|
||||
$md5=1;
|
||||
$ctx="%r11";
|
||||
$inp="%r15";
|
||||
$code.=<<___;
|
||||
mov %rsp,$ctx
|
||||
mov $in0,$inp
|
||||
___
|
||||
}
|
||||
}
|
||||
$code.=<<___;
|
||||
#rc4# add $TX[0]#b,$YY#b
|
||||
#rc4# lea ($dat,$XX[0],4),$XX[1]
|
||||
shl \$6,$len
|
||||
add $inp,$len # pointer to the end of input
|
||||
mov $len,16(%rsp)
|
||||
|
||||
#md5# mov $ctx,24(%rsp) # save pointer to MD5_CTX
|
||||
#md5# mov 0*4($ctx),$V[0] # load current hash value from MD5_CTX
|
||||
#md5# mov 1*4($ctx),$V[1]
|
||||
#md5# mov 2*4($ctx),$V[2]
|
||||
#md5# mov 3*4($ctx),$V[3]
|
||||
jmp .Loop
|
||||
|
||||
.align 16
|
||||
.Loop:
|
||||
#md5# mov $V[0],0*4(%rsp) # put aside current hash value
|
||||
#md5# mov $V[1],1*4(%rsp)
|
||||
#md5# mov $V[2],2*4(%rsp)
|
||||
#md5# mov $V[3],$tmp # forward reference
|
||||
#md5# mov $V[3],3*4(%rsp)
|
||||
___
|
||||
|
||||
sub R0 {
|
||||
my ($i,$a,$b,$c,$d)=@_;
|
||||
my @rot0=(7,12,17,22);
|
||||
my $j=$i%16;
|
||||
my $k=$i%$MOD;
|
||||
my $xmm="%xmm".($j&1);
|
||||
$code.=" movdqu ($in0),%xmm2\n" if ($rc4 && $j==15);
|
||||
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
|
||||
$code.=<<___;
|
||||
#rc4# movl ($dat,$YY,4),$TY#d
|
||||
#md5# xor $c,$tmp
|
||||
#rc4# movl $TX[0]#d,($dat,$YY,4)
|
||||
#md5# and $b,$tmp
|
||||
#md5# add 4*`$j`($inp),$a
|
||||
#rc4# add $TY#b,$TX[0]#b
|
||||
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
|
||||
#md5# add \$$K[$i],$a
|
||||
#md5# xor $d,$tmp
|
||||
#rc4# movz $TX[0]#b,$TX[0]#d
|
||||
#rc4# movl $TY#d,4*$k($XX[1])
|
||||
#md5# add $tmp,$a
|
||||
#rc4# add $TX[1]#b,$YY#b
|
||||
#md5# rol \$$rot0[$j%4],$a
|
||||
#md5# mov `$j==15?"$b":"$c"`,$tmp # forward reference
|
||||
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
|
||||
#md5# add $b,$a
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
mov $YY,$XX[1]
|
||||
xor $YY,$YY # keyword to partial register
|
||||
mov $XX[1]#b,$YY#b
|
||||
lea ($dat,$XX[0],4),$XX[1]
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15);
|
||||
psllq \$8,%xmm1
|
||||
pxor %xmm0,%xmm2
|
||||
pxor %xmm1,%xmm2
|
||||
___
|
||||
}
|
||||
sub R1 {
|
||||
my ($i,$a,$b,$c,$d)=@_;
|
||||
my @rot1=(5,9,14,20);
|
||||
my $j=$i%16;
|
||||
my $k=$i%$MOD;
|
||||
my $xmm="%xmm".($j&1);
|
||||
$code.=" movdqu 16($in0),%xmm3\n" if ($rc4 && $j==15);
|
||||
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
|
||||
$code.=<<___;
|
||||
#rc4# movl ($dat,$YY,4),$TY#d
|
||||
#md5# xor $b,$tmp
|
||||
#rc4# movl $TX[0]#d,($dat,$YY,4)
|
||||
#md5# and $d,$tmp
|
||||
#md5# add 4*`((1+5*$j)%16)`($inp),$a
|
||||
#rc4# add $TY#b,$TX[0]#b
|
||||
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
|
||||
#md5# add \$$K[$i],$a
|
||||
#md5# xor $c,$tmp
|
||||
#rc4# movz $TX[0]#b,$TX[0]#d
|
||||
#rc4# movl $TY#d,4*$k($XX[1])
|
||||
#md5# add $tmp,$a
|
||||
#rc4# add $TX[1]#b,$YY#b
|
||||
#md5# rol \$$rot1[$j%4],$a
|
||||
#md5# mov `$j==15?"$c":"$b"`,$tmp # forward reference
|
||||
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
|
||||
#md5# add $b,$a
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
mov $YY,$XX[1]
|
||||
xor $YY,$YY # keyword to partial register
|
||||
mov $XX[1]#b,$YY#b
|
||||
lea ($dat,$XX[0],4),$XX[1]
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15);
|
||||
psllq \$8,%xmm1
|
||||
pxor %xmm0,%xmm3
|
||||
pxor %xmm1,%xmm3
|
||||
___
|
||||
}
|
||||
sub R2 {
|
||||
my ($i,$a,$b,$c,$d)=@_;
|
||||
my @rot2=(4,11,16,23);
|
||||
my $j=$i%16;
|
||||
my $k=$i%$MOD;
|
||||
my $xmm="%xmm".($j&1);
|
||||
$code.=" movdqu 32($in0),%xmm4\n" if ($rc4 && $j==15);
|
||||
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
|
||||
$code.=<<___;
|
||||
#rc4# movl ($dat,$YY,4),$TY#d
|
||||
#md5# xor $c,$tmp
|
||||
#rc4# movl $TX[0]#d,($dat,$YY,4)
|
||||
#md5# xor $b,$tmp
|
||||
#md5# add 4*`((5+3*$j)%16)`($inp),$a
|
||||
#rc4# add $TY#b,$TX[0]#b
|
||||
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
|
||||
#md5# add \$$K[$i],$a
|
||||
#rc4# movz $TX[0]#b,$TX[0]#d
|
||||
#md5# add $tmp,$a
|
||||
#rc4# movl $TY#d,4*$k($XX[1])
|
||||
#rc4# add $TX[1]#b,$YY#b
|
||||
#md5# rol \$$rot2[$j%4],$a
|
||||
#md5# mov `$j==15?"\\\$-1":"$c"`,$tmp # forward reference
|
||||
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
|
||||
#md5# add $b,$a
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
mov $YY,$XX[1]
|
||||
xor $YY,$YY # keyword to partial register
|
||||
mov $XX[1]#b,$YY#b
|
||||
lea ($dat,$XX[0],4),$XX[1]
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15);
|
||||
psllq \$8,%xmm1
|
||||
pxor %xmm0,%xmm4
|
||||
pxor %xmm1,%xmm4
|
||||
___
|
||||
}
|
||||
sub R3 {
|
||||
my ($i,$a,$b,$c,$d)=@_;
|
||||
my @rot3=(6,10,15,21);
|
||||
my $j=$i%16;
|
||||
my $k=$i%$MOD;
|
||||
my $xmm="%xmm".($j&1);
|
||||
$code.=" movdqu 48($in0),%xmm5\n" if ($rc4 && $j==15);
|
||||
$code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1);
|
||||
$code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1);
|
||||
$code.=<<___;
|
||||
#rc4# movl ($dat,$YY,4),$TY#d
|
||||
#md5# xor $d,$tmp
|
||||
#rc4# movl $TX[0]#d,($dat,$YY,4)
|
||||
#md5# or $b,$tmp
|
||||
#md5# add 4*`((7*$j)%16)`($inp),$a
|
||||
#rc4# add $TY#b,$TX[0]#b
|
||||
#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d
|
||||
#md5# add \$$K[$i],$a
|
||||
#rc4# movz $TX[0]#b,$TX[0]#d
|
||||
#md5# xor $c,$tmp
|
||||
#rc4# movl $TY#d,4*$k($XX[1])
|
||||
#md5# add $tmp,$a
|
||||
#rc4# add $TX[1]#b,$YY#b
|
||||
#md5# rol \$$rot3[$j%4],$a
|
||||
#md5# mov \$-1,$tmp # forward reference
|
||||
#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n
|
||||
#md5# add $b,$a
|
||||
___
|
||||
$code.=<<___ if ($rc4 && $j==15);
|
||||
mov $XX[0],$XX[1]
|
||||
xor $XX[0],$XX[0] # keyword to partial register
|
||||
mov $XX[1]#b,$XX[0]#b
|
||||
mov $YY,$XX[1]
|
||||
xor $YY,$YY # keyword to partial register
|
||||
mov $XX[1]#b,$YY#b
|
||||
lea ($dat,$XX[0],4),$XX[1]
|
||||
psllq \$8,%xmm1
|
||||
pxor %xmm0,%xmm5
|
||||
pxor %xmm1,%xmm5
|
||||
___
|
||||
}
|
||||
|
||||
my $i=0;
|
||||
for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
|
||||
for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
|
||||
for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
|
||||
for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); }
|
||||
|
||||
$code.=<<___;
|
||||
#md5# add 0*4(%rsp),$V[0] # accumulate hash value
|
||||
#md5# add 1*4(%rsp),$V[1]
|
||||
#md5# add 2*4(%rsp),$V[2]
|
||||
#md5# add 3*4(%rsp),$V[3]
|
||||
|
||||
#rc4# movdqu %xmm2,($out,$in0) # write RC4 output
|
||||
#rc4# movdqu %xmm3,16($out,$in0)
|
||||
#rc4# movdqu %xmm4,32($out,$in0)
|
||||
#rc4# movdqu %xmm5,48($out,$in0)
|
||||
#md5# lea 64($inp),$inp
|
||||
#rc4# lea 64($in0),$in0
|
||||
cmp 16(%rsp),$inp # are we done?
|
||||
jb .Loop
|
||||
|
||||
#md5# mov 24(%rsp),$len # restore pointer to MD5_CTX
|
||||
#rc4# sub $TX[0]#b,$YY#b # correct $YY
|
||||
#md5# mov $V[0],0*4($len) # write MD5_CTX
|
||||
#md5# mov $V[1],1*4($len)
|
||||
#md5# mov $V[2],2*4($len)
|
||||
#md5# mov $V[3],3*4($len)
|
||||
___
|
||||
$code.=<<___ if ($rc4 && (!$md5 || $D));
|
||||
mov 32(%rsp),$len # restore original $len
|
||||
and \$63,$len # remaining bytes
|
||||
jnz .Loop1
|
||||
jmp .Ldone
|
||||
|
||||
.align 16
|
||||
.Loop1:
|
||||
add $TX[0]#b,$YY#b
|
||||
movl ($dat,$YY,4),$TY#d
|
||||
movl $TX[0]#d,($dat,$YY,4)
|
||||
movl $TY#d,($dat,$XX[0],4)
|
||||
add $TY#b,$TX[0]#b
|
||||
inc $XX[0]#b
|
||||
movl ($dat,$TX[0],4),$TY#d
|
||||
movl ($dat,$XX[0],4),$TX[0]#d
|
||||
xorb ($in0),$TY#b
|
||||
movb $TY#b,($out,$in0)
|
||||
lea 1($in0),$in0
|
||||
dec $len
|
||||
jnz .Loop1
|
||||
|
||||
.Ldone:
|
||||
___
|
||||
$code.=<<___;
|
||||
#rc4# sub \$1,$XX[0]#b
|
||||
#rc4# movl $XX[0]#d,-8($dat)
|
||||
#rc4# movl $YY#d,-4($dat)
|
||||
|
||||
mov 40(%rsp),%r15
|
||||
mov 48(%rsp),%r14
|
||||
mov 56(%rsp),%r13
|
||||
mov 64(%rsp),%r12
|
||||
mov 72(%rsp),%rbp
|
||||
mov 80(%rsp),%rbx
|
||||
lea 88(%rsp),%rsp
|
||||
.Lepilogue:
|
||||
.Labort:
|
||||
ret
|
||||
.size $func,.-$func
|
||||
___
|
||||
|
||||
if ($rc4 && $D) { # sole purpose of this section is to provide
|
||||
# option to use the generated module as drop-in
|
||||
# replacement for rc4-x86_64.pl for debugging
|
||||
# and testing purposes...
|
||||
my ($idx,$ido)=("%r8","%r9");
|
||||
my ($dat,$len,$inp)=("%rdi","%rsi","%rdx");
|
||||
|
||||
$code.=<<___;
|
||||
.globl RC4_set_key
|
||||
.type RC4_set_key,\@function,3
|
||||
.align 16
|
||||
RC4_set_key:
|
||||
lea 8($dat),$dat
|
||||
lea ($inp,$len),$inp
|
||||
neg $len
|
||||
mov $len,%rcx
|
||||
xor %eax,%eax
|
||||
xor $ido,$ido
|
||||
xor %r10,%r10
|
||||
xor %r11,%r11
|
||||
jmp .Lw1stloop
|
||||
|
||||
.align 16
|
||||
.Lw1stloop:
|
||||
mov %eax,($dat,%rax,4)
|
||||
add \$1,%al
|
||||
jnc .Lw1stloop
|
||||
|
||||
xor $ido,$ido
|
||||
xor $idx,$idx
|
||||
.align 16
|
||||
.Lw2ndloop:
|
||||
mov ($dat,$ido,4),%r10d
|
||||
add ($inp,$len,1),$idx#b
|
||||
add %r10b,$idx#b
|
||||
add \$1,$len
|
||||
mov ($dat,$idx,4),%r11d
|
||||
cmovz %rcx,$len
|
||||
mov %r10d,($dat,$idx,4)
|
||||
mov %r11d,($dat,$ido,4)
|
||||
add \$1,$ido#b
|
||||
jnc .Lw2ndloop
|
||||
|
||||
xor %eax,%eax
|
||||
mov %eax,-8($dat)
|
||||
mov %eax,-4($dat)
|
||||
ret
|
||||
.size RC4_set_key,.-RC4_set_key
|
||||
|
||||
.globl RC4_options
|
||||
.type RC4_options,\@abi-omnipotent
|
||||
.align 16
|
||||
RC4_options:
|
||||
lea .Lopts(%rip),%rax
|
||||
ret
|
||||
.align 64
|
||||
.Lopts:
|
||||
.asciz "rc4(64x,int)"
|
||||
.align 64
|
||||
.size RC4_options,.-RC4_options
|
||||
___
|
||||
}
|
||||
# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
|
||||
# CONTEXT *context,DISPATCHER_CONTEXT *disp)
|
||||
if ($win64) {
|
||||
my $rec="%rcx";
|
||||
my $frame="%rdx";
|
||||
my $context="%r8";
|
||||
my $disp="%r9";
|
||||
|
||||
$code.=<<___;
|
||||
.extern __imp_RtlVirtualUnwind
|
||||
.type se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
push %rbp
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
pushfq
|
||||
sub \$64,%rsp
|
||||
|
||||
mov 120($context),%rax # pull context->Rax
|
||||
mov 248($context),%rbx # pull context->Rip
|
||||
|
||||
lea .Lbody(%rip),%r10
|
||||
cmp %r10,%rbx # context->Rip<.Lbody
|
||||
jb .Lin_prologue
|
||||
|
||||
mov 152($context),%rax # pull context->Rsp
|
||||
|
||||
lea .Lepilogue(%rip),%r10
|
||||
cmp %r10,%rbx # context->Rip>=.Lepilogue
|
||||
jae .Lin_prologue
|
||||
|
||||
mov 40(%rax),%r15
|
||||
mov 48(%rax),%r14
|
||||
mov 56(%rax),%r13
|
||||
mov 64(%rax),%r12
|
||||
mov 72(%rax),%rbp
|
||||
mov 80(%rax),%rbx
|
||||
lea 88(%rax),%rax
|
||||
|
||||
mov %rbx,144($context) # restore context->Rbx
|
||||
mov %rbp,160($context) # restore context->Rbp
|
||||
mov %r12,216($context) # restore context->R12
|
||||
mov %r13,224($context) # restore context->R12
|
||||
mov %r14,232($context) # restore context->R14
|
||||
mov %r15,240($context) # restore context->R15
|
||||
|
||||
.Lin_prologue:
|
||||
mov 8(%rax),%rdi
|
||||
mov 16(%rax),%rsi
|
||||
mov %rax,152($context) # restore context->Rsp
|
||||
mov %rsi,168($context) # restore context->Rsi
|
||||
mov %rdi,176($context) # restore context->Rdi
|
||||
|
||||
mov 40($disp),%rdi # disp->ContextRecord
|
||||
mov $context,%rsi # context
|
||||
mov \$154,%ecx # sizeof(CONTEXT)
|
||||
.long 0xa548f3fc # cld; rep movsq
|
||||
|
||||
mov $disp,%rsi
|
||||
xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER
|
||||
mov 8(%rsi),%rdx # arg2, disp->ImageBase
|
||||
mov 0(%rsi),%r8 # arg3, disp->ControlPc
|
||||
mov 16(%rsi),%r9 # arg4, disp->FunctionEntry
|
||||
mov 40(%rsi),%r10 # disp->ContextRecord
|
||||
lea 56(%rsi),%r11 # &disp->HandlerData
|
||||
lea 24(%rsi),%r12 # &disp->EstablisherFrame
|
||||
mov %r10,32(%rsp) # arg5
|
||||
mov %r11,40(%rsp) # arg6
|
||||
mov %r12,48(%rsp) # arg7
|
||||
mov %rcx,56(%rsp) # arg8, (NULL)
|
||||
call *__imp_RtlVirtualUnwind(%rip)
|
||||
|
||||
mov \$1,%eax # ExceptionContinueSearch
|
||||
add \$64,%rsp
|
||||
popfq
|
||||
pop %r15
|
||||
pop %r14
|
||||
pop %r13
|
||||
pop %r12
|
||||
pop %rbp
|
||||
pop %rbx
|
||||
pop %rdi
|
||||
pop %rsi
|
||||
ret
|
||||
.size se_handler,.-se_handler
|
||||
|
||||
.section .pdata
|
||||
.align 4
|
||||
.rva .LSEH_begin_$func
|
||||
.rva .LSEH_end_$func
|
||||
.rva .LSEH_info_$func
|
||||
|
||||
.section .xdata
|
||||
.align 8
|
||||
.LSEH_info_$func:
|
||||
.byte 9,0,0,0
|
||||
.rva se_handler
|
||||
___
|
||||
}
|
||||
|
||||
sub reg_part {
|
||||
my ($reg,$conv)=@_;
|
||||
if ($reg =~ /%r[0-9]+/) { $reg .= $conv; }
|
||||
elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; }
|
||||
elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; }
|
||||
elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; }
|
||||
return $reg;
|
||||
}
|
||||
|
||||
$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem;
|
||||
$code =~ s/\`([^\`]*)\`/eval $1/gem;
|
||||
$code =~ s/pinsrw\s+\$0,/movd /gm;
|
||||
|
||||
$code =~ s/#md5#//gm if ($md5);
|
||||
$code =~ s/#rc4#//gm if ($rc4);
|
||||
|
||||
print $code;
|
||||
|
||||
close STDOUT;
|
||||
+22
-43
@@ -56,6 +56,7 @@
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/digest.h>
|
||||
@@ -65,6 +66,7 @@
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "../internal.h"
|
||||
|
||||
/* TODO(fork): don't the check functions have to be constant time? */
|
||||
|
||||
@@ -191,51 +193,30 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* constant_time_byte_eq returns 1 if |x| == |y| and 0 otherwise. */
|
||||
static int constant_time_byte_eq(unsigned char a, unsigned char b) {
|
||||
unsigned char z = ~(a ^ b);
|
||||
z &= z >> 4;
|
||||
z &= z >> 2;
|
||||
z &= z >> 1;
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
/* constant_time_select returns |x| if |v| is 1 and |y| if |v| is 0.
|
||||
* Its behavior is undefined if |v| takes any other value. */
|
||||
static int constant_time_select(int v, int x, int y) {
|
||||
return ((~(v - 1)) & x) | ((v - 1) & y);
|
||||
}
|
||||
|
||||
/* constant_time_le returns 1 if |x| <= |y| and 0 otherwise.
|
||||
* |x| and |y| must be positive. */
|
||||
static int constant_time_le(int x, int y) {
|
||||
return ((x - y - 1) >> (sizeof(int) * 8 - 1)) & 1;
|
||||
}
|
||||
|
||||
int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
|
||||
size_t *out_index) {
|
||||
size_t i;
|
||||
int first_byte_is_zero, second_byte_is_two, looking_for_index;
|
||||
int valid_index, zero_index = 0;
|
||||
unsigned first_byte_is_zero, second_byte_is_two, looking_for_index;
|
||||
unsigned valid_index, zero_index = 0;
|
||||
|
||||
/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
|
||||
* Standard", section 7.2.2. */
|
||||
if (from_len < RSA_PKCS1_PADDING_SIZE) {
|
||||
if (from_len < RSA_PKCS1_PADDING_SIZE || from_len > UINT_MAX) {
|
||||
/* |from| is zero-padded to the size of the RSA modulus, a public value, so
|
||||
* this can be rejected in non-constant time. */
|
||||
* this can be rejected in non-constant time. This logic also requires
|
||||
* |from_len| fit in an |unsigned|. */
|
||||
*out_index = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
first_byte_is_zero = constant_time_byte_eq(from[0], 0);
|
||||
second_byte_is_two = constant_time_byte_eq(from[1], 2);
|
||||
first_byte_is_zero = constant_time_eq(from[0], 0);
|
||||
second_byte_is_two = constant_time_eq(from[1], 2);
|
||||
|
||||
looking_for_index = 1;
|
||||
looking_for_index = ~0u;
|
||||
for (i = 2; i < from_len; i++) {
|
||||
int equals0 = constant_time_byte_eq(from[i], 0);
|
||||
zero_index =
|
||||
constant_time_select(looking_for_index & equals0, i, zero_index);
|
||||
unsigned equals0 = constant_time_is_zero(from[i]);
|
||||
zero_index = constant_time_select(looking_for_index & equals0, (unsigned)i,
|
||||
zero_index);
|
||||
looking_for_index = constant_time_select(equals0, 0, looking_for_index);
|
||||
}
|
||||
|
||||
@@ -247,13 +228,13 @@ int RSA_message_index_PKCS1_type_2(const uint8_t *from, size_t from_len,
|
||||
valid_index &= ~looking_for_index;
|
||||
|
||||
/* PS must be at least 8 bytes long, and it starts two bytes into |from|. */
|
||||
valid_index &= constant_time_le(2 + 8, zero_index);
|
||||
valid_index &= constant_time_ge(zero_index, 2 + 8);
|
||||
|
||||
/* Skip the zero byte. */
|
||||
zero_index++;
|
||||
|
||||
*out_index = constant_time_select(valid_index, zero_index, 0);
|
||||
return valid_index;
|
||||
return constant_time_select(valid_index, 1, 0);
|
||||
}
|
||||
|
||||
int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
|
||||
@@ -421,10 +402,9 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
|
||||
const uint8_t *from, unsigned flen,
|
||||
const uint8_t *param, unsigned plen,
|
||||
const EVP_MD *md, const EVP_MD *mgf1md) {
|
||||
unsigned i, dblen, mlen = -1, mdlen;
|
||||
unsigned i, dblen, mlen = -1, mdlen, bad, looking_for_one_byte, one_index = 0;
|
||||
const uint8_t *maskeddb, *maskedseed;
|
||||
uint8_t *db = NULL, seed[EVP_MAX_MD_SIZE], phash[EVP_MAX_MD_SIZE];
|
||||
int bad, looking_for_one_byte, one_index = 0;
|
||||
|
||||
if (md == NULL) {
|
||||
md = EVP_sha1();
|
||||
@@ -472,15 +452,14 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
|
||||
goto err;
|
||||
}
|
||||
|
||||
bad = CRYPTO_memcmp(db, phash, mdlen);
|
||||
bad |= from[0];
|
||||
bad = ~constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
|
||||
bad |= ~constant_time_is_zero(from[0]);
|
||||
|
||||
looking_for_one_byte = 1;
|
||||
looking_for_one_byte = ~0u;
|
||||
for (i = mdlen; i < dblen; i++) {
|
||||
int equals1 = constant_time_byte_eq(db[i], 1);
|
||||
int equals0 = constant_time_byte_eq(db[i], 0);
|
||||
one_index =
|
||||
constant_time_select(looking_for_one_byte & equals1, i, one_index);
|
||||
unsigned equals1 = constant_time_eq(db[i], 1);
|
||||
unsigned equals0 = constant_time_eq(db[i], 0);
|
||||
one_index = constant_time_select(looking_for_one_byte & equals1, i, one_index);
|
||||
looking_for_one_byte =
|
||||
constant_time_select(equals1, 0, looking_for_one_byte);
|
||||
bad |= looking_for_one_byte & ~equals0;
|
||||
|
||||
+4
-10
@@ -96,13 +96,7 @@ RSA *RSA_new_method(const ENGINE *engine) {
|
||||
rsa->references = 1;
|
||||
rsa->flags = rsa->meth->flags;
|
||||
CRYPTO_MUTEX_init(&rsa->lock);
|
||||
|
||||
if (!CRYPTO_new_ex_data(&g_ex_data_class, rsa, &rsa->ex_data)) {
|
||||
CRYPTO_MUTEX_cleanup(&rsa->lock);
|
||||
METHOD_unref(rsa->meth);
|
||||
OPENSSL_free(rsa);
|
||||
return NULL;
|
||||
}
|
||||
CRYPTO_new_ex_data(&rsa->ex_data);
|
||||
|
||||
if (rsa->meth->init && !rsa->meth->init(rsa)) {
|
||||
CRYPTO_free_ex_data(&g_ex_data_class, rsa, &rsa->ex_data);
|
||||
@@ -308,11 +302,11 @@ int RSA_supports_digest(const RSA *rsa, const EVP_MD *md) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) {
|
||||
int index;
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
|
||||
dup_func, free_func)) {
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, dup_func,
|
||||
free_func)) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
|
||||
@@ -636,7 +636,7 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
|
||||
BIGNUM *p = NULL, *q = NULL;
|
||||
|
||||
/* Make sure BN_mod_inverse in Montgomery intialization uses the
|
||||
* BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */
|
||||
* BN_FLG_CONSTTIME flag. */
|
||||
BN_init(&local_p);
|
||||
p = &local_p;
|
||||
BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
|
||||
|
||||
@@ -121,9 +121,7 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
|
||||
# In upstream, this is controlled by shelling out to the compiler to check
|
||||
# versions, but BoringSSL is intended to be used with pre-generated perlasm
|
||||
# output, so this isn't useful anyway.
|
||||
#
|
||||
# TODO(davidben): Enable this after testing. $ymm goes up to 1.
|
||||
$ymm = 0;
|
||||
$ymm = 1;
|
||||
|
||||
$ymm = 0 unless ($xmm);
|
||||
|
||||
|
||||
@@ -96,8 +96,10 @@ die "can't locate x86_64-xlate.pl";
|
||||
# versions, but BoringSSL is intended to be used with pre-generated perlasm
|
||||
# output, so this isn't useful anyway.
|
||||
#
|
||||
# TODO(davidben): Enable this after testing. $avx goes up to 2.
|
||||
$avx = 0;
|
||||
# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it
|
||||
# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream
|
||||
# did not tie them together until after $shaext was added.
|
||||
$avx = 1;
|
||||
|
||||
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
|
||||
# been tested.
|
||||
|
||||
@@ -72,8 +72,8 @@ for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); }
|
||||
# versions, but BoringSSL is intended to be used with pre-generated perlasm
|
||||
# output, so this isn't useful anyway.
|
||||
#
|
||||
# TODO(davidben): Enable this after testing. $avx goes up to 2.
|
||||
$avx = 0;
|
||||
# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2.
|
||||
$avx = 1;
|
||||
|
||||
$avx = 0 unless ($xmm);
|
||||
|
||||
|
||||
@@ -113,8 +113,10 @@ die "can't locate x86_64-xlate.pl";
|
||||
# versions, but BoringSSL is intended to be used with pre-generated perlasm
|
||||
# output, so this isn't useful anyway.
|
||||
#
|
||||
# TODO(davidben): Enable this after testing. $avx goes up to 2.
|
||||
$avx = 0;
|
||||
# TODO(davidben): Enable AVX2 code after testing by setting $avx to 2. Is it
|
||||
# necessary to disable AVX2 code when SHA Extensions code is disabled? Upstream
|
||||
# did not tie them together until after $shaext was added.
|
||||
$avx = 1;
|
||||
|
||||
# TODO(davidben): Consider enabling the Intel SHA Extensions code once it's
|
||||
# been tested.
|
||||
|
||||
+6
-5
@@ -102,21 +102,22 @@ uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) {
|
||||
do { \
|
||||
uint32_t ll; \
|
||||
ll = (c)->h[0]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[1]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[2]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[3]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
ll = (c)->h[4]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} while (0)
|
||||
|
||||
#define HASH_UPDATE SHA1_Update
|
||||
#define HASH_TRANSFORM SHA1_Transform
|
||||
#define HASH_FINAL SHA1_Final
|
||||
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
#define Xupdate(a, ix, ia, ib, ic, id) \
|
||||
((a) = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE((a), 1))
|
||||
|
||||
|
||||
+5
-3
@@ -155,13 +155,13 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
|
||||
case SHA224_DIGEST_LENGTH: \
|
||||
for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \
|
||||
ll = (c)->h[nn]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} \
|
||||
break; \
|
||||
case SHA256_DIGEST_LENGTH: \
|
||||
for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \
|
||||
ll = (c)->h[nn]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} \
|
||||
break; \
|
||||
default: \
|
||||
@@ -170,7 +170,7 @@ int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) {
|
||||
} \
|
||||
for (nn = 0; nn < (c)->md_len / 4; nn++) { \
|
||||
ll = (c)->h[nn]; \
|
||||
(void) HOST_l2c(ll, (s)); \
|
||||
HOST_l2c(ll, (s)); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
@@ -204,6 +204,8 @@ static const uint32_t K256[64] = {
|
||||
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL};
|
||||
|
||||
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
|
||||
/* FIPS specification refers to right rotations, while our ROTATE macro
|
||||
* is left one. This is why you might notice that rotation coefficients
|
||||
* differ from those observed in FIPS document by 32-N... */
|
||||
|
||||
+89
-77
@@ -60,8 +60,6 @@
|
||||
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
/* IMPLEMENTATION NOTES.
|
||||
*
|
||||
@@ -87,14 +85,14 @@
|
||||
#endif
|
||||
|
||||
int SHA384_Init(SHA512_CTX *sha) {
|
||||
sha->h[0] = OPENSSL_U64(0xcbbb9d5dc1059ed8);
|
||||
sha->h[1] = OPENSSL_U64(0x629a292a367cd507);
|
||||
sha->h[2] = OPENSSL_U64(0x9159015a3070dd17);
|
||||
sha->h[3] = OPENSSL_U64(0x152fecd8f70e5939);
|
||||
sha->h[4] = OPENSSL_U64(0x67332667ffc00b31);
|
||||
sha->h[5] = OPENSSL_U64(0x8eb44a8768581511);
|
||||
sha->h[6] = OPENSSL_U64(0xdb0c2e0d64f98fa7);
|
||||
sha->h[7] = OPENSSL_U64(0x47b5481dbefa4fa4);
|
||||
sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8);
|
||||
sha->h[1] = UINT64_C(0x629a292a367cd507);
|
||||
sha->h[2] = UINT64_C(0x9159015a3070dd17);
|
||||
sha->h[3] = UINT64_C(0x152fecd8f70e5939);
|
||||
sha->h[4] = UINT64_C(0x67332667ffc00b31);
|
||||
sha->h[5] = UINT64_C(0x8eb44a8768581511);
|
||||
sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7);
|
||||
sha->h[7] = UINT64_C(0x47b5481dbefa4fa4);
|
||||
|
||||
sha->Nl = 0;
|
||||
sha->Nh = 0;
|
||||
@@ -105,14 +103,14 @@ int SHA384_Init(SHA512_CTX *sha) {
|
||||
|
||||
|
||||
int SHA512_Init(SHA512_CTX *sha) {
|
||||
sha->h[0] = OPENSSL_U64(0x6a09e667f3bcc908);
|
||||
sha->h[1] = OPENSSL_U64(0xbb67ae8584caa73b);
|
||||
sha->h[2] = OPENSSL_U64(0x3c6ef372fe94f82b);
|
||||
sha->h[3] = OPENSSL_U64(0xa54ff53a5f1d36f1);
|
||||
sha->h[4] = OPENSSL_U64(0x510e527fade682d1);
|
||||
sha->h[5] = OPENSSL_U64(0x9b05688c2b3e6c1f);
|
||||
sha->h[6] = OPENSSL_U64(0x1f83d9abfb41bd6b);
|
||||
sha->h[7] = OPENSSL_U64(0x5be0cd19137e2179);
|
||||
sha->h[0] = UINT64_C(0x6a09e667f3bcc908);
|
||||
sha->h[1] = UINT64_C(0xbb67ae8584caa73b);
|
||||
sha->h[2] = UINT64_C(0x3c6ef372fe94f82b);
|
||||
sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1);
|
||||
sha->h[4] = UINT64_C(0x510e527fade682d1);
|
||||
sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f);
|
||||
sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b);
|
||||
sha->h[7] = UINT64_C(0x5be0cd19137e2179);
|
||||
|
||||
sha->Nl = 0;
|
||||
sha->Nh = 0;
|
||||
@@ -185,7 +183,7 @@ int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
l = (c->Nl + (((uint64_t)len) << 3)) & OPENSSL_U64(0xffffffffffffffff);
|
||||
l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff);
|
||||
if (l < c->Nl) {
|
||||
c->Nh++;
|
||||
}
|
||||
@@ -316,77 +314,91 @@ int SHA512_Final(uint8_t *md, SHA512_CTX *sha) {
|
||||
|
||||
#ifndef SHA512_ASM
|
||||
static const uint64_t K512[80] = {
|
||||
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
|
||||
0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
|
||||
0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
|
||||
0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
|
||||
0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
|
||||
0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
|
||||
0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
|
||||
0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
|
||||
0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
|
||||
0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
|
||||
0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
|
||||
0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
|
||||
0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
|
||||
0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
|
||||
0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
|
||||
0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
|
||||
0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
|
||||
0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
|
||||
0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
|
||||
0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
|
||||
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
|
||||
0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
|
||||
0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
|
||||
0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
|
||||
0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
|
||||
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
|
||||
0x5fcb6fab3ad6faec, 0x6c44198c4a475817};
|
||||
UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd),
|
||||
UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc),
|
||||
UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019),
|
||||
UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118),
|
||||
UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe),
|
||||
UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2),
|
||||
UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1),
|
||||
UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694),
|
||||
UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3),
|
||||
UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65),
|
||||
UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483),
|
||||
UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5),
|
||||
UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210),
|
||||
UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4),
|
||||
UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725),
|
||||
UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70),
|
||||
UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926),
|
||||
UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df),
|
||||
UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8),
|
||||
UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b),
|
||||
UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001),
|
||||
UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30),
|
||||
UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910),
|
||||
UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8),
|
||||
UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53),
|
||||
UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8),
|
||||
UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb),
|
||||
UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3),
|
||||
UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60),
|
||||
UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec),
|
||||
UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9),
|
||||
UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b),
|
||||
UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207),
|
||||
UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178),
|
||||
UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6),
|
||||
UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b),
|
||||
UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493),
|
||||
UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c),
|
||||
UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a),
|
||||
UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817),
|
||||
};
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM)
|
||||
#if defined(__x86_64) || defined(__x86_64__)
|
||||
#define ROTR(a, n) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
asm("rorq %1,%0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \
|
||||
ret; \
|
||||
#define ROTR(a, n) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
__asm__("rorq %1, %0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \
|
||||
ret; \
|
||||
})
|
||||
#define PULL64(x) \
|
||||
({ \
|
||||
uint64_t ret = *((const uint64_t *)(&(x))); \
|
||||
asm("bswapq %0" : "=r"(ret) : "0"(ret)); \
|
||||
ret; \
|
||||
#define PULL64(x) \
|
||||
({ \
|
||||
uint64_t ret = *((const uint64_t *)(&(x))); \
|
||||
__asm__("bswapq %0" : "=r"(ret) : "0"(ret)); \
|
||||
ret; \
|
||||
})
|
||||
#elif(defined(__i386) || defined(__i386__))
|
||||
#define PULL64(x) \
|
||||
({ \
|
||||
const unsigned int *p = (const unsigned int *)(&(x)); \
|
||||
unsigned int hi = p[0], lo = p[1]; \
|
||||
asm("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \
|
||||
((uint64_t)hi) << 32 | lo; \
|
||||
#define PULL64(x) \
|
||||
({ \
|
||||
const unsigned int *p = (const unsigned int *)(&(x)); \
|
||||
unsigned int hi = p[0], lo = p[1]; \
|
||||
__asm__("bswapl %0; bswapl %1;" : "=r"(lo), "=r"(hi) : "0"(lo), "1"(hi)); \
|
||||
((uint64_t)hi) << 32 | lo; \
|
||||
})
|
||||
#elif(defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
|
||||
#define ROTR(a, n) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
asm("rotrdi %0,%1,%2" : "=r"(ret) : "r"(a), "K"(n)); \
|
||||
ret; \
|
||||
#define ROTR(a, n) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
__asm__("rotrdi %0, %1, %2" : "=r"(ret) : "r"(a), "K"(n)); \
|
||||
ret; \
|
||||
})
|
||||
#elif defined(__aarch64__)
|
||||
#define ROTR(a, n) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
asm("ror %0,%1,%2" : "=r"(ret) : "r"(a), "I"(n)); \
|
||||
ret; \
|
||||
#define ROTR(a, n) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
__asm__("ror %0, %1, %2" : "=r"(ret) : "r"(a), "I"(n)); \
|
||||
ret; \
|
||||
})
|
||||
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
|
||||
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
#define PULL64(x) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
asm("rev %0,%1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \
|
||||
ret; \
|
||||
#define PULL64(x) \
|
||||
({ \
|
||||
uint64_t ret; \
|
||||
__asm__("rev %0, %1" : "=r"(ret) : "r"(*((const uint64_t *)(&(x))))); \
|
||||
ret; \
|
||||
})
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/aead.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/cmac.h>
|
||||
@@ -95,6 +96,7 @@ class ScopedOpenSSLContext {
|
||||
T ctx_;
|
||||
};
|
||||
|
||||
using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
|
||||
using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
|
||||
using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
|
||||
using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_THREADS)
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -74,7 +75,11 @@ void CRYPTO_STATIC_MUTEX_unlock(struct CRYPTO_STATIC_MUTEX *lock) {
|
||||
}
|
||||
|
||||
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
|
||||
pthread_once(once, init);
|
||||
if (pthread_once(once, init) != 0) {
|
||||
fprintf(stderr,
|
||||
"pthread_once failed. Did you link against a threading library?\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -98,7 +98,7 @@ static void free_dir(X509_LOOKUP *lu);
|
||||
static int add_cert_dir(BY_DIR *ctx,const char *dir,int type);
|
||||
static int get_cert_by_subject(X509_LOOKUP *xl,int type,X509_NAME *name,
|
||||
X509_OBJECT *ret);
|
||||
X509_LOOKUP_METHOD x509_dir_lookup=
|
||||
static X509_LOOKUP_METHOD x509_dir_lookup=
|
||||
{
|
||||
"Load certs from files in a directory",
|
||||
new_dir, /* new */
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
|
||||
static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
|
||||
long argl, char **ret);
|
||||
X509_LOOKUP_METHOD x509_file_lookup=
|
||||
static X509_LOOKUP_METHOD x509_file_lookup=
|
||||
{
|
||||
"Load file into cache",
|
||||
NULL, /* new */
|
||||
|
||||
+9
-2
@@ -15,6 +15,7 @@
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/err.h>
|
||||
@@ -114,8 +115,11 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (CBS_len(&cert) > LONG_MAX) {
|
||||
goto err;
|
||||
}
|
||||
inp = CBS_data(&cert);
|
||||
x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
|
||||
x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert));
|
||||
if (!x509) {
|
||||
goto err;
|
||||
}
|
||||
@@ -181,8 +185,11 @@ int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (CBS_len(&crl_data) > LONG_MAX) {
|
||||
goto err;
|
||||
}
|
||||
inp = CBS_data(&crl_data);
|
||||
crl = d2i_X509_CRL(NULL, &inp, CBS_len(&crl_data));
|
||||
crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data));
|
||||
if (!crl) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
+4
-14
@@ -141,7 +141,6 @@ static int check_crl_chain(X509_STORE_CTX *ctx,
|
||||
STACK_OF(X509) *crl_path);
|
||||
|
||||
static int internal_verify(X509_STORE_CTX *ctx);
|
||||
const char X509_version[]="X.509";
|
||||
|
||||
|
||||
static int null_callback(int ok, X509_STORE_CTX *e)
|
||||
@@ -2093,14 +2092,14 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
|
||||
{
|
||||
/* This function is (usually) called only once, by
|
||||
* SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). */
|
||||
int index;
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
|
||||
new_func, dup_func, free_func))
|
||||
dup_func, free_func))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -2267,19 +2266,13 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
|
||||
STACK_OF(X509) *chain)
|
||||
{
|
||||
int ret = 1;
|
||||
int ex_data_allocated = 0;
|
||||
|
||||
memset(ctx, 0, sizeof(X509_STORE_CTX));
|
||||
ctx->ctx=store;
|
||||
ctx->cert=x509;
|
||||
ctx->untrusted=chain;
|
||||
|
||||
if(!CRYPTO_new_ex_data(&g_ex_data_class, ctx,
|
||||
&ctx->ex_data))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
ex_data_allocated = 1;
|
||||
CRYPTO_new_ex_data(&ctx->ex_data);
|
||||
|
||||
ctx->param = X509_VERIFY_PARAM_new();
|
||||
if (!ctx->param)
|
||||
@@ -2363,10 +2356,7 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
|
||||
return 1;
|
||||
|
||||
err:
|
||||
if (ex_data_allocated)
|
||||
{
|
||||
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
|
||||
}
|
||||
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
|
||||
if (ctx->param != NULL)
|
||||
{
|
||||
X509_VERIFY_PARAM_free(ctx->param);
|
||||
|
||||
@@ -120,7 +120,7 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
|
||||
* to the external form.
|
||||
*/
|
||||
|
||||
const ASN1_EXTERN_FUNCS x509_name_ff = {
|
||||
static const ASN1_EXTERN_FUNCS x509_name_ff = {
|
||||
NULL,
|
||||
x509_name_ex_new,
|
||||
x509_name_ex_free,
|
||||
|
||||
@@ -104,7 +104,7 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
ret->akid = NULL;
|
||||
ret->aux = NULL;
|
||||
ret->crldp = NULL;
|
||||
CRYPTO_new_ex_data(&g_ex_data_class, ret, &ret->ex_data);
|
||||
CRYPTO_new_ex_data(&ret->ex_data);
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_POST:
|
||||
@@ -146,12 +146,12 @@ X509 *X509_up_ref(X509 *x)
|
||||
return x;
|
||||
}
|
||||
|
||||
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
|
||||
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
|
||||
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
|
||||
{
|
||||
int index;
|
||||
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
|
||||
new_func, dup_func, free_func))
|
||||
dup_func, free_func))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
+11
-11
@@ -55,17 +55,17 @@
|
||||
|
||||
/* This file contains a table of "standard" extensions */
|
||||
|
||||
extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
|
||||
extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
|
||||
extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
|
||||
extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
|
||||
extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
|
||||
extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
|
||||
extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
|
||||
extern X509V3_EXT_METHOD v3_crl_hold, v3_pci;
|
||||
extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
|
||||
extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
|
||||
extern X509V3_EXT_METHOD v3_addr, v3_asid;
|
||||
extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
|
||||
extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
|
||||
extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id;
|
||||
extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
|
||||
extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
|
||||
extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
|
||||
extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
|
||||
extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci;
|
||||
extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
|
||||
extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
|
||||
extern const X509V3_EXT_METHOD v3_addr, v3_asid;
|
||||
|
||||
/* This table will be searched using OBJ_bsearch so it *must* kept in
|
||||
* order of the ext_nid values.
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#include "../macros.h"
|
||||
|
||||
|
||||
@@ -80,15 +81,6 @@ void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, const CAST_KEY *ks,
|
||||
l2n(d[1], out);
|
||||
}
|
||||
|
||||
extern const uint32_t CAST_S_table0[256];
|
||||
extern const uint32_t CAST_S_table1[256];
|
||||
extern const uint32_t CAST_S_table2[256];
|
||||
extern const uint32_t CAST_S_table3[256];
|
||||
extern const uint32_t CAST_S_table4[256];
|
||||
extern const uint32_t CAST_S_table5[256];
|
||||
extern const uint32_t CAST_S_table6[256];
|
||||
extern const uint32_t CAST_S_table7[256];
|
||||
|
||||
#if defined(OPENSSL_WINDOWS) && defined(_MSC_VER)
|
||||
#define ROTL(a, n) (_lrotl(a, n))
|
||||
#else
|
||||
|
||||
@@ -56,6 +56,9 @@
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
const uint32_t CAST_S_table0[256] = {
|
||||
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
|
||||
0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.] */
|
||||
|
||||
#ifndef OPENSSL_HEADER_CAST_INTERNAL_H
|
||||
#define OPENSSL_HEADER_CAST_INTERNAL_H
|
||||
|
||||
#include <openssl/base.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern const uint32_t CAST_S_table0[256];
|
||||
extern const uint32_t CAST_S_table1[256];
|
||||
extern const uint32_t CAST_S_table2[256];
|
||||
extern const uint32_t CAST_S_table3[256];
|
||||
extern const uint32_t CAST_S_table4[256];
|
||||
extern const uint32_t CAST_S_table5[256];
|
||||
extern const uint32_t CAST_S_table6[256];
|
||||
extern const uint32_t CAST_S_table7[256];
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
#endif /* OPENSSL_HEADER_CAST_INTERNAL_H */
|
||||
+23
-61
@@ -56,12 +56,6 @@
|
||||
#include "../crypto/modes/internal.h"
|
||||
|
||||
|
||||
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64)
|
||||
#define STRICT_ALIGNMENT 0
|
||||
#else
|
||||
#define STRICT_ALIGNMENT 1
|
||||
#endif
|
||||
|
||||
typedef struct xts128_context {
|
||||
void *key1, *key2;
|
||||
block128_f block1, block2;
|
||||
@@ -70,10 +64,6 @@ typedef struct xts128_context {
|
||||
static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
|
||||
const uint8_t iv[16], const uint8_t *inp,
|
||||
uint8_t *out, size_t len, int enc) {
|
||||
const union {
|
||||
long one;
|
||||
char little;
|
||||
} is_endian = {1};
|
||||
union {
|
||||
uint64_t u[2];
|
||||
uint32_t d[4];
|
||||
@@ -90,22 +80,22 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
|
||||
if (!enc && (len % 16)) len -= 16;
|
||||
|
||||
while (len >= 16) {
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
#if STRICT_ALIGNMENT
|
||||
memcpy(scratch.c, inp, 16);
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
#else
|
||||
scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak.u[0];
|
||||
scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak.u[1];
|
||||
scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak.u[0];
|
||||
scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak.u[1];
|
||||
#endif
|
||||
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
#if STRICT_ALIGNMENT
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
memcpy(out, scratch.c, 16);
|
||||
#else
|
||||
((unint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
|
||||
((unint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
|
||||
((uint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
|
||||
((uint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
|
||||
#endif
|
||||
inp += 16;
|
||||
out += 16;
|
||||
@@ -113,26 +103,12 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
|
||||
|
||||
if (len == 0) return 1;
|
||||
|
||||
if (is_endian.little) {
|
||||
unsigned int carry, res;
|
||||
unsigned int carry, res;
|
||||
|
||||
res = 0x87 & (((int)tweak.d[3]) >> 31);
|
||||
carry = (unsigned int)(tweak.u[0] >> 63);
|
||||
tweak.u[0] = (tweak.u[0] << 1) ^ res;
|
||||
tweak.u[1] = (tweak.u[1] << 1) | carry;
|
||||
} else {
|
||||
size_t c;
|
||||
|
||||
for (c = 0, i = 0; i < 16; ++i) {
|
||||
/*
|
||||
* + substitutes for |, because c is 1 bit
|
||||
*/
|
||||
c += ((size_t)tweak.c[i]) << 1;
|
||||
tweak.c[i] = (uint8_t)c;
|
||||
c = c >> 8;
|
||||
}
|
||||
tweak.c[0] ^= (uint8_t)(0x87 & (0 - c));
|
||||
}
|
||||
res = 0x87 & (((int)tweak.d[3]) >> 31);
|
||||
carry = (unsigned int)(tweak.u[0] >> 63);
|
||||
tweak.u[0] = (tweak.u[0] << 1) ^ res;
|
||||
tweak.u[1] = (tweak.u[1] << 1) | carry;
|
||||
}
|
||||
if (enc) {
|
||||
for (i = 0; i < len; ++i) {
|
||||
@@ -152,33 +128,19 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
|
||||
uint8_t c[16];
|
||||
} tweak1;
|
||||
|
||||
if (is_endian.little) {
|
||||
unsigned int carry, res;
|
||||
unsigned int carry, res;
|
||||
|
||||
res = 0x87 & (((int)tweak.d[3]) >> 31);
|
||||
carry = (unsigned int)(tweak.u[0] >> 63);
|
||||
tweak1.u[0] = (tweak.u[0] << 1) ^ res;
|
||||
tweak1.u[1] = (tweak.u[1] << 1) | carry;
|
||||
} else {
|
||||
size_t c;
|
||||
|
||||
for (c = 0, i = 0; i < 16; ++i) {
|
||||
/*
|
||||
* + substitutes for |, because c is 1 bit
|
||||
*/
|
||||
c += ((size_t)tweak.c[i]) << 1;
|
||||
tweak1.c[i] = (uint8_t)c;
|
||||
c = c >> 8;
|
||||
}
|
||||
tweak1.c[0] ^= (uint8_t)(0x87 & (0 - c));
|
||||
}
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
res = 0x87 & (((int)tweak.d[3]) >> 31);
|
||||
carry = (unsigned int)(tweak.u[0] >> 63);
|
||||
tweak1.u[0] = (tweak.u[0] << 1) ^ res;
|
||||
tweak1.u[1] = (tweak.u[1] << 1) | carry;
|
||||
#if STRICT_ALIGNMENT
|
||||
memcpy(scratch.c, inp, 16);
|
||||
scratch.u[0] ^= tweak1.u[0];
|
||||
scratch.u[1] ^= tweak1.u[1];
|
||||
#else
|
||||
scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak1.u[0];
|
||||
scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak1.u[1];
|
||||
scratch.u[0] = ((uint64_t *)inp)[0] ^ tweak1.u[0];
|
||||
scratch.u[1] = ((uint64_t *)inp)[1] ^ tweak1.u[1];
|
||||
#endif
|
||||
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
|
||||
scratch.u[0] ^= tweak1.u[0];
|
||||
@@ -192,13 +154,13 @@ static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
(*ctx->block1)(scratch.c, scratch.c, ctx->key1);
|
||||
#if defined(STRICT_ALIGNMENT)
|
||||
#if STRICT_ALIGNMENT
|
||||
scratch.u[0] ^= tweak.u[0];
|
||||
scratch.u[1] ^= tweak.u[1];
|
||||
memcpy(out, scratch.c, 16);
|
||||
#else
|
||||
((unint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
|
||||
((unint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
|
||||
((uint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
|
||||
((uint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -286,7 +248,7 @@ static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
|
||||
}
|
||||
|
||||
static const EVP_CIPHER aes_256_xts = {
|
||||
NID_aes_256_xts, 1 /* block_size */, 32 /* key_size */,
|
||||
NID_aes_256_xts, 1 /* block_size */, 64 /* key_size (2 AES keys) */,
|
||||
16 /* iv_len */, sizeof(EVP_AES_XTS_CTX),
|
||||
EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT |
|
||||
EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY,
|
||||
|
||||
+12
-12
@@ -98,23 +98,15 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
|
||||
/* EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. */
|
||||
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
|
||||
|
||||
/* EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and
|
||||
* Poly1305 as described in RFC 7539. */
|
||||
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
|
||||
|
||||
/* EVP_aead_chacha20_poly1305_old is an AEAD built from ChaCha20 and
|
||||
* Poly1305 that is used in the experimental ChaCha20-Poly1305 TLS cipher
|
||||
* suites. */
|
||||
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_old(void);
|
||||
|
||||
/* EVP_aead_chacha20_poly1305 is currently an alias for
|
||||
* |EVP_aead_chacha20_poly1305_old|. In the future, the RFC 7539 version will
|
||||
* take this name. */
|
||||
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
|
||||
|
||||
/* EVP_aead_chacha20_poly1305_rfc7539 is the AEAD built from ChaCha20 and
|
||||
* Poly1305 as described in RFC 7539.
|
||||
*
|
||||
* WARNING: this function is not ready yet. It will be renamed in the future to
|
||||
* drop the “_rfc7539” suffix. */
|
||||
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
|
||||
|
||||
/* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be
|
||||
* used except to interoperate with existing systems that use this mode.
|
||||
*
|
||||
@@ -339,6 +331,14 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx,
|
||||
const uint8_t **out_iv, size_t *out_len);
|
||||
|
||||
|
||||
/* Deprecated functions. */
|
||||
|
||||
/* EVP_aead_chacha20_poly1305_rfc7539 calls |EVP_aead_chacha20_poly1305|.
|
||||
*
|
||||
* TODO(davidben): Remove this. */
|
||||
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} /* extern C */
|
||||
#endif
|
||||
|
||||
@@ -85,6 +85,9 @@ extern "C" {
|
||||
#define V_ASN1_ANY -4 /* used in ASN1 template code */
|
||||
|
||||
#define V_ASN1_NEG 0x100 /* negative flag */
|
||||
/* No supported universal tags may exceed this value, to avoid ambiguity with
|
||||
* V_ASN1_NEG. */
|
||||
#define V_ASN1_MAX_UNIVERSAL 0xff
|
||||
|
||||
#define V_ASN1_UNDEF -1
|
||||
#define V_ASN1_EOC 0
|
||||
|
||||
@@ -836,11 +836,7 @@ struct bignum_st {
|
||||
struct bn_mont_ctx_st {
|
||||
BIGNUM RR; /* used to convert to montgomery form */
|
||||
BIGNUM N; /* The modulus */
|
||||
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
|
||||
* (Ni is only stored for bignum algorithm) */
|
||||
BN_ULONG n0[2]; /* least significant word(s) of Ni;
|
||||
(type changed with 0.9.9, was "BN_ULONG n0;" before) */
|
||||
int ri; /* number of bits in R */
|
||||
BN_ULONG n0[2]; /* least significant words of (R*Ri-1)/N */
|
||||
};
|
||||
|
||||
OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l);
|
||||
|
||||
@@ -238,13 +238,13 @@ struct cbb_buffer_st {
|
||||
|
||||
struct cbb_st {
|
||||
struct cbb_buffer_st *base;
|
||||
/* offset is the offset from the start of |base->buf| to the position of any
|
||||
* pending length-prefix. */
|
||||
size_t offset;
|
||||
/* child points to a child CBB if a length-prefix is pending. */
|
||||
CBB *child;
|
||||
/* pending_len_len contains the number of bytes in a pending length-prefix,
|
||||
* or zero if no length-prefix is pending. */
|
||||
/* offset is the number of bytes from the start of |base->buf| to this |CBB|'s
|
||||
* pending length prefix. */
|
||||
size_t offset;
|
||||
/* pending_len_len contains the number of bytes in this |CBB|'s pending
|
||||
* length-prefix, or zero if no length-prefix is pending. */
|
||||
uint8_t pending_len_len;
|
||||
char pending_is_asn1;
|
||||
/* is_top_level is true iff this is a top-level |CBB| (as opposed to a child
|
||||
@@ -292,12 +292,11 @@ OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
|
||||
* on error. */
|
||||
OPENSSL_EXPORT int CBB_flush(CBB *cbb);
|
||||
|
||||
/* CBB_len returns the number of bytes written to |cbb|'s top-level |CBB|. It
|
||||
* may be compared before and after an operation to determine how many bytes
|
||||
* were written.
|
||||
/* CBB_len returns the number of bytes written to |cbb|. It does not flush
|
||||
* |cbb|.
|
||||
*
|
||||
* It is a fatal error to call this on a CBB with any active children. This does
|
||||
* not flush |cbb|. */
|
||||
* To avoid unfinalized length prefixes, it is a fatal error to call this on a
|
||||
* CBB with any active children. */
|
||||
OPENSSL_EXPORT size_t CBB_len(const CBB *cbb);
|
||||
|
||||
/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user