summaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto')
-rw-r--r--src/crypto/CMakeLists.txt2
-rw-r--r--src/crypto/cipher_extra/aead_test.cc1
-rw-r--r--src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl122
-rw-r--r--src/crypto/cipher_extra/e_aesgcmsiv.c8
-rw-r--r--src/crypto/cipher_extra/e_chacha20poly1305.c74
-rw-r--r--src/crypto/fipsmodule/CMakeLists.txt11
-rw-r--r--src/crypto/fipsmodule/bn/exponentiation.c9
-rw-r--r--src/crypto/fipsmodule/ec/ec_test.cc25
-rw-r--r--src/crypto/fipsmodule/ec/example_mul.c133
-rw-r--r--src/crypto/fipsmodule/ec/p224-64.c14
-rw-r--r--src/crypto/fipsmodule/ec/p256-64.c26
-rw-r--r--src/crypto/x509v3/CMakeLists.txt22
-rw-r--r--src/crypto/x509v3/ext_dat.h8
-rw-r--r--src/crypto/x509v3/tab_test.cc (renamed from src/crypto/x509v3/tab_test.c)56
-rw-r--r--src/crypto/x509v3/v3name_test.cc (renamed from src/crypto/x509v3/v3name_test.c)30
15 files changed, 267 insertions, 274 deletions
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index b941f67d..651793fd 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -260,6 +260,8 @@ add_executable(
test/file_test_gtest.cc
thread_test.cc
x509/x509_test.cc
+ x509v3/tab_test.cc
+ x509v3/v3name_test.cc
$<TARGET_OBJECTS:crypto_test_data>
$<TARGET_OBJECTS:gtest_main>
diff --git a/src/crypto/cipher_extra/aead_test.cc b/src/crypto/cipher_extra/aead_test.cc
index 949c8002..a699890a 100644
--- a/src/crypto/cipher_extra/aead_test.cc
+++ b/src/crypto/cipher_extra/aead_test.cc
@@ -240,6 +240,7 @@ TEST_P(PerAEADTest, TestExtraInput) {
for (size_t extra_in_size = 0; extra_in_size < in.size(); extra_in_size++) {
size_t tag_bytes_written;
+ SCOPED_TRACE(extra_in_size);
ASSERT_TRUE(EVP_AEAD_CTX_seal_scatter(
ctx.get(), out.data(), out_tag.data(), &tag_bytes_written,
out_tag.size(), nonce.data(), nonce.size(), in.data(),
diff --git a/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl b/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
index 857f1d5d..0e322798 100644
--- a/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
+++ b/src/crypto/cipher_extra/asm/chacha20_poly1305_x86_64.pl
@@ -78,6 +78,7 @@ chacha20_poly1305_constants:
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00
.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00
+.byte 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
___
my ($oup,$inp,$inl,$adp,$keyp,$itr1,$itr2)=("%rdi","%rsi","%rbx","%rcx","%r9","%rcx","%r8");
@@ -856,7 +857,9 @@ chacha20_poly1305_seal:
.cfi_offset r15, -56
lea 32(%rsp), %rbp
and \$-32, %rbp
- mov %rdx, 8+$len_store
+ mov 56($keyp), $inl # extra_in_len
+ addq %rdx, $inl
+ mov $inl, 8+$len_store
mov %r8, 0+$len_store
mov %rdx, $inl\n"; $code.="
mov OPENSSL_ia32cap_P+8(%rip), %eax
@@ -1093,11 +1096,9 @@ seal_sse_128_seal:
seal_sse_tail_16:
test $inl, $inl
- jz seal_sse_finalize
+ jz process_blocks_of_extra_in
# We can only load the PT one byte at a time to avoid buffer overread
mov $inl, $itr2
- shl \$4, $itr2
- lea .and_masks(%rip), $t0
mov $inl, $itr1
lea -1($inp, $inl), $inp
pxor $T3, $T3
@@ -1106,7 +1107,7 @@ seal_sse_tail_16:
pinsrb \$0, ($inp), $T3
lea -1($inp), $inp
dec $itr1
- jne 1b
+ jne 1b
# XOR the keystream with the plaintext.
pxor $A0, $T3
@@ -1121,14 +1122,121 @@ seal_sse_tail_16:
sub \$1, $itr1
jnz 2b
- pand -16($t0, $itr2), $T3
+ # $T3 contains the final (partial, non-empty) block of ciphertext which
+ # needs to be fed into the Poly1305 state. The right-most $inl bytes of it
+ # are valid. We need to fill it with extra_in bytes until full, or until we
+ # run out of bytes.
+ #
+ # $keyp points to the tag output, which is actually a struct with the
+ # extra_in pointer and length at offset 48.
+ movq 288+32(%rsp), $keyp
+ movq 56($keyp), $t1 # extra_in_len
+ movq 48($keyp), $t0 # extra_in
+ test $t1, $t1
+ jz process_partial_block # Common case: no bytes of extra_in
+
+ movq \$16, $t2
+ subq $inl, $t2 # 16-$inl is the number of bytes that fit into $T3.
+ cmpq $t2, $t1 # if extra_in_len < 16-$inl, only copy extra_in_len
+ # (note that AT&T syntax reverses the arguments)
+ jge load_extra_in
+ movq $t1, $t2
+
+load_extra_in:
+ # $t2 contains the number of bytes of extra_in (pointed to by $t0) to load
+ # into $T3. They are loaded in reverse order.
+ leaq -1($t0, $t2), $inp
+ # Update extra_in and extra_in_len to reflect the bytes that are about to
+ # be read.
+ addq $t2, $t0
+ subq $t2, $t1
+ movq $t0, 48($keyp)
+ movq $t1, 56($keyp)
+
+ # Update $itr2, which is used to select the mask later on, to reflect the
+ # extra bytes about to be added.
+ addq $t2, $itr2
+
+ # Load $t2 bytes of extra_in into $T2.
+ pxor $T2, $T2
+3:
+ pslldq \$1, $T2
+ pinsrb \$0, ($inp), $T2
+ lea -1($inp), $inp
+ sub \$1, $t2
+ jnz 3b
+
+ # Shift $T2 up the length of the remainder from the main encryption. Sadly,
+ # the shift for an XMM register has to be a constant, thus we loop to do
+ # this.
+ movq $inl, $t2
+
+4:
+ pslldq \$1, $T2
+ sub \$1, $t2
+ jnz 4b
+
+ # Mask $T3 (the remainder from the main encryption) so that superfluous
+ # bytes are zero. This means that the non-zero bytes in $T2 and $T3 are
+ # disjoint and so we can merge them with an OR.
+ lea .and_masks(%rip), $t2
+ shl \$4, $inl
+ pand -16($t2, $inl), $T3
+
+ # Merge $T2 into $T3, forming the remainder block.
+ por $T2, $T3
+
+ # The block of ciphertext + extra_in is ready to be included in the
+ # Poly1305 state.
+ movq $T3, $t0
+ pextrq \$1, $T3, $t1
+ add $t0, $acc0
+ adc $t1, $acc1
+ adc \$1, $acc2\n";
+ &poly_mul(); $code.="
+
+process_blocks_of_extra_in:
+ # There may be additional bytes of extra_in to process.
+ movq 288+32(%rsp), $keyp
+ movq 48($keyp), $inp # extra_in
+ movq 56($keyp), $itr2 # extra_in_len
+ movq $itr2, $itr1
+ shr \$4, $itr2 # number of blocks
+
+5:
+ jz process_extra_in_trailer\n";
+ &poly_add("0($inp)");
+ &poly_mul(); $code.="
+ leaq 16($inp), $inp
+ subq \$1, $itr2
+ jmp 5b
+
+process_extra_in_trailer:
+ andq \$15, $itr1 # remaining num bytes (<16) of extra_in
+ movq $itr1, $inl
+ jz do_length_block
+ leaq -1($inp, $itr1), $inp
+
+6:
+ pslldq \$1, $T3
+ pinsrb \$0, ($inp), $T3
+ lea -1($inp), $inp
+ sub \$1, $itr1
+ jnz 6b
+
+process_partial_block:
+ # $T3 contains $inl bytes of data to be fed into Poly1305. $inl != 0
+ lea .and_masks(%rip), $t2
+ shl \$4, $inl
+ pand -16($t2, $inl), $T3
movq $T3, $t0
pextrq \$1, $T3, $t1
add $t0, $acc0
adc $t1, $acc1
adc \$1, $acc2\n";
&poly_mul(); $code.="
-seal_sse_finalize:\n";
+
+do_length_block:\n";
&poly_add($len_store);
&poly_mul(); $code.="
# Final reduce
diff --git a/src/crypto/cipher_extra/e_aesgcmsiv.c b/src/crypto/cipher_extra/e_aesgcmsiv.c
index 190a1b96..2dd12670 100644
--- a/src/crypto/cipher_extra/e_aesgcmsiv.c
+++ b/src/crypto/cipher_extra/e_aesgcmsiv.c
@@ -13,6 +13,9 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <openssl/aead.h>
+
+#include <assert.h>
+
#include <openssl/cipher.h>
#include <openssl/cpu.h>
#include <openssl/crypto.h>
@@ -29,7 +32,7 @@
/* Optimised AES-GCM-SIV */
struct aead_aes_gcm_siv_asm_ctx {
- alignas(64) uint8_t key[16*15];
+ alignas(16) uint8_t key[16*15];
int is_128_bit;
};
@@ -67,6 +70,9 @@ static int aead_aes_gcm_siv_asm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
return 0;
}
+ /* malloc should return a 16-byte-aligned address. */
+ assert((((uintptr_t)gcm_siv_ctx) & 15) == 0);
+
if (key_bits == 128) {
aes128gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]);
gcm_siv_ctx->is_128_bit = 1;
diff --git a/src/crypto/cipher_extra/e_chacha20poly1305.c b/src/crypto/cipher_extra/e_chacha20poly1305.c
index 6cfc856c..515b60f2 100644
--- a/src/crypto/cipher_extra/e_chacha20poly1305.c
+++ b/src/crypto/cipher_extra/e_chacha20poly1305.c
@@ -124,33 +124,34 @@ static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) {
CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
}
-static void poly1305_update_padded_16(poly1305_state *poly1305,
- const uint8_t *data, size_t data_len) {
- static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
-
- CRYPTO_poly1305_update(poly1305, data, data_len);
- if (data_len % 16 != 0) {
- CRYPTO_poly1305_update(poly1305, padding,
- sizeof(padding) - (data_len % 16));
- }
-}
-
/* calc_tag fills |tag| with the authentication tag for the given inputs. */
static void calc_tag(uint8_t tag[POLY1305_TAG_LEN],
const struct aead_chacha20_poly1305_ctx *c20_ctx,
const uint8_t nonce[12], const uint8_t *ad, size_t ad_len,
- const uint8_t *ciphertext, size_t ciphertext_len) {
+ const uint8_t *ciphertext, size_t ciphertext_len,
+ const uint8_t *ciphertext_extra,
+ size_t ciphertext_extra_len) {
alignas(16) uint8_t poly1305_key[32];
OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key));
CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key),
c20_ctx->key, nonce, 0);
+ static const uint8_t padding[16] = { 0 }; /* Padding is all zeros. */
poly1305_state ctx;
CRYPTO_poly1305_init(&ctx, poly1305_key);
- poly1305_update_padded_16(&ctx, ad, ad_len);
- poly1305_update_padded_16(&ctx, ciphertext, ciphertext_len);
+ CRYPTO_poly1305_update(&ctx, ad, ad_len);
+ if (ad_len % 16 != 0) {
+ CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16));
+ }
+ CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len);
+ CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len);
+ const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len;
+ if (ciphertext_total % 16 != 0) {
+ CRYPTO_poly1305_update(&ctx, padding,
+ sizeof(padding) - (ciphertext_total % 16));
+ }
poly1305_update_length(&ctx, ad_len);
- poly1305_update_length(&ctx, ciphertext_len);
+ poly1305_update_length(&ctx, ciphertext_total);
CRYPTO_poly1305_finish(&ctx, tag);
}
@@ -161,6 +162,14 @@ static int aead_chacha20_poly1305_seal_scatter(
size_t extra_in_len, const uint8_t *ad, size_t ad_len) {
const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
+ if (extra_in_len + ctx->tag_len < ctx->tag_len) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
+ return 0;
+ }
+ if (max_out_tag_len < ctx->tag_len + extra_in_len) {
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
if (nonce_len != 12) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
@@ -183,20 +192,43 @@ static int aead_chacha20_poly1305_seal_scatter(
return 0;
}
- alignas(16) uint8_t tag[48];
+ /* The the extra input is given, it is expected to be very short and so is
+ * encrypted byte-by-byte first. */
+ if (extra_in_len) {
+ static const size_t kChaChaBlockSize = 64;
+ uint32_t block_counter = 1 + (in_len / kChaChaBlockSize);
+ size_t offset = in_len % kChaChaBlockSize;
+ uint8_t block[64 /* kChaChaBlockSize */];
+
+ for (size_t done = 0; done < extra_in_len; block_counter++) {
+ memset(block, 0, sizeof(block));
+ CRYPTO_chacha_20(block, block, sizeof(block), c20_ctx->key, nonce,
+ block_counter);
+ for (size_t i = offset; i < sizeof(block) && done < extra_in_len;
+ i++, done++) {
+ out_tag[done] = extra_in[done] ^ block[i];
+ }
+ offset = 0;
+ }
+ }
+
+ alignas(16) uint8_t tag[48 + 8 + 8];
if (asm_capable()) {
OPENSSL_memcpy(tag, c20_ctx->key, 32);
OPENSSL_memset(tag + 32, 0, 4);
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
+ OPENSSL_memcpy(tag + 48, &out_tag, sizeof(out_tag));
+ OPENSSL_memcpy(tag + 56, &extra_in_len, sizeof(extra_in_len));
chacha20_poly1305_seal(out, in, in_len, ad, ad_len, tag);
} else {
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
- calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len);
+ calc_tag(tag, c20_ctx, nonce, ad, ad_len, out, in_len,
+ out_tag, extra_in_len);
}
- OPENSSL_memcpy(out_tag, tag, ctx->tag_len);
- *out_tag_len = ctx->tag_len;
+ OPENSSL_memcpy(out_tag + extra_in_len, tag, ctx->tag_len);
+ *out_tag_len = extra_in_len + ctx->tag_len;
return 1;
}
@@ -236,7 +268,7 @@ static int aead_chacha20_poly1305_open_gather(
OPENSSL_memcpy(tag + 32 + 4, nonce, 12);
chacha20_poly1305_open(out, in, in_len, ad, ad_len, tag);
} else {
- calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len);
+ calc_tag(tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0);
CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1);
}
@@ -253,7 +285,7 @@ static const EVP_AEAD aead_chacha20_poly1305 = {
12, /* nonce len */
POLY1305_TAG_LEN, /* overhead */
POLY1305_TAG_LEN, /* max tag length */
- 0, /* seal_scatter_supports_extra_in */
+ 1, /* seal_scatter_supports_extra_in */
aead_chacha20_poly1305_init,
NULL, /* init_with_direction */
diff --git a/src/crypto/fipsmodule/CMakeLists.txt b/src/crypto/fipsmodule/CMakeLists.txt
index a1bc6dc9..e83c4835 100644
--- a/src/crypto/fipsmodule/CMakeLists.txt
+++ b/src/crypto/fipsmodule/CMakeLists.txt
@@ -193,14 +193,3 @@ else()
${BCM_ASM_SOURCES}
)
endif()
-
-add_executable(
- example_mul
-
- ec/example_mul.c
-
- $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(example_mul crypto)
-add_dependencies(all_tests example_mul)
diff --git a/src/crypto/fipsmodule/bn/exponentiation.c b/src/crypto/fipsmodule/bn/exponentiation.c
index e5521d68..187b845c 100644
--- a/src/crypto/fipsmodule/bn/exponentiation.c
+++ b/src/crypto/fipsmodule/bn/exponentiation.c
@@ -1085,11 +1085,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
while (bits >= 0) {
/* Read five bits from |bits-4| through |bits|, inclusive. */
int first_bit = bits - 4;
- wvalue = *(const uint16_t *) (p_bytes + (first_bit >> 3));
- wvalue >>= first_bit & 7;
- wvalue &= 0x1f;
+ uint16_t val;
+ OPENSSL_memcpy(&val, p_bytes + (first_bit >> 3), sizeof(val));
+ val >>= first_bit & 7;
+ val &= 0x1f;
bits -= 5;
- bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+ bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val);
}
}
diff --git a/src/crypto/fipsmodule/ec/ec_test.cc b/src/crypto/fipsmodule/ec/ec_test.cc
index 71f9fd80..48b60ee9 100644
--- a/src/crypto/fipsmodule/ec/ec_test.cc
+++ b/src/crypto/fipsmodule/ec/ec_test.cc
@@ -380,6 +380,31 @@ TEST_P(ECCurveTest, MulZero) {
<< "p * 0 did not return point at infinity.";
}
+// Test that 10×∞ + G = G.
+TEST_P(ECCurveTest, Mul) {
+ bssl::UniquePtr<EC_GROUP> group(EC_GROUP_new_by_curve_name(GetParam().nid));
+ ASSERT_TRUE(group);
+ bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group.get()));
+ ASSERT_TRUE(p);
+ bssl::UniquePtr<EC_POINT> result(EC_POINT_new(group.get()));
+ ASSERT_TRUE(result);
+ bssl::UniquePtr<BIGNUM> n(BN_new());
+ ASSERT_TRUE(n);
+ ASSERT_TRUE(EC_POINT_set_to_infinity(group.get(), p.get()));
+ ASSERT_TRUE(BN_set_word(n.get(), 10));
+
+ // First check that 10×∞ = ∞.
+ ASSERT_TRUE(EC_POINT_mul(group.get(), result.get(), nullptr, p.get(), n.get(),
+ nullptr));
+ EXPECT_TRUE(EC_POINT_is_at_infinity(group.get(), result.get()));
+
+ // Now check that 10×∞ + G = G.
+ const EC_POINT *generator = EC_GROUP_get0_generator(group.get());
+ ASSERT_TRUE(EC_POINT_mul(group.get(), result.get(), BN_value_one(), p.get(),
+ n.get(), nullptr));
+ EXPECT_EQ(0, EC_POINT_cmp(group.get(), result.get(), generator, nullptr));
+}
+
static std::vector<EC_builtin_curve> AllCurves() {
const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
std::vector<EC_builtin_curve> curves(num_curves);
diff --git a/src/crypto/fipsmodule/ec/example_mul.c b/src/crypto/fipsmodule/ec/example_mul.c
deleted file mode 100644
index a2bdd527..00000000
--- a/src/crypto/fipsmodule/ec/example_mul.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Originally written by Bodo Moeller for the OpenSSL project.
- * ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * 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 above 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 acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED 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 OpenSSL PROJECT OR
- * ITS 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.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- *
- * Portions of the attached software ("Contribution") are developed by
- * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
- *
- * The Contribution is licensed pursuant to the OpenSSL open source
- * license provided above.
- *
- * The elliptic curve binary polynomial software is originally written by
- * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
- * Laboratories. */
-
-#include <stdio.h>
-
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/ec.h>
-#include <openssl/nid.h>
-
-
-static int example_EC_POINT_mul(void) {
- /* This example ensures that 10×∞ + G = G, in P-256. */
- EC_GROUP *group = NULL;
- EC_POINT *p = NULL, *result = NULL;
- BIGNUM *n = NULL;
- int ret = 0;
- const EC_POINT *generator;
-
- group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
- p = EC_POINT_new(group);
- result = EC_POINT_new(group);
- n = BN_new();
-
- if (p == NULL ||
- result == NULL ||
- group == NULL ||
- n == NULL ||
- !EC_POINT_set_to_infinity(group, p) ||
- !BN_set_word(n, 10)) {
- goto err;
- }
-
- /* First check that 10×∞ = ∞. */
- if (!EC_POINT_mul(group, result, NULL, p, n, NULL) ||
- !EC_POINT_is_at_infinity(group, result)) {
- goto err;
- }
-
- generator = EC_GROUP_get0_generator(group);
-
- /* Now check that 10×∞ + G = G. */
- if (!EC_POINT_mul(group, result, BN_value_one(), p, n, NULL) ||
- EC_POINT_cmp(group, result, generator, NULL) != 0) {
- goto err;
- }
-
- ret = 1;
-
-err:
- BN_free(n);
- EC_POINT_free(result);
- EC_POINT_free(p);
- EC_GROUP_free(group);
-
- return ret;
-}
-
-int main(void) {
- CRYPTO_library_init();
-
- if (!example_EC_POINT_mul()) {
- fprintf(stderr, "failed\n");
- return 1;
- }
-
- printf("PASS\n");
- return 0;
-}
diff --git a/src/crypto/fipsmodule/ec/p224-64.c b/src/crypto/fipsmodule/ec/p224-64.c
index 31097d43..67dfcc85 100644
--- a/src/crypto/fipsmodule/ec/p224-64.c
+++ b/src/crypto/fipsmodule/ec/p224-64.c
@@ -181,12 +181,18 @@ static const p224_felem g_p224_pre_comp[2][16][3] = {
{0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
{1, 0, 0, 0}}}};
+static uint64_t p224_load_u64(const uint8_t in[8]) {
+ uint64_t ret;
+ OPENSSL_memcpy(&ret, in, sizeof(ret));
+ return ret;
+}
+
/* Helper functions to convert field elements to/from internal representation */
static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) {
- out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
- out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
- out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
- out[3] = (*((const uint64_t *)(in + 20))) >> 8;
+ out[0] = p224_load_u64(in) & 0x00ffffffffffffff;
+ out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff;
+ out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff;
+ out[3] = p224_load_u64(in + 20) >> 8;
}
static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) {
diff --git a/src/crypto/fipsmodule/ec/p256-64.c b/src/crypto/fipsmodule/ec/p256-64.c
index de1edc2b..8952aa2e 100644
--- a/src/crypto/fipsmodule/ec/p256-64.c
+++ b/src/crypto/fipsmodule/ec/p256-64.c
@@ -71,22 +71,32 @@ static const uint64_t kPrime[4] = {0xfffffffffffffffful, 0xffffffff, 0,
0xffffffff00000001ul};
static const uint64_t bottom63bits = 0x7ffffffffffffffful;
+static uint64_t load_u64(const uint8_t in[8]) {
+ uint64_t ret;
+ OPENSSL_memcpy(&ret, in, sizeof(ret));
+ return ret;
+}
+
+static void store_u64(uint8_t out[8], uint64_t in) {
+ OPENSSL_memcpy(out, &in, sizeof(in));
+}
+
/* bin32_to_felem takes a little-endian byte array and converts it into felem
* form. This assumes that the CPU is little-endian. */
static void bin32_to_felem(felem out, const uint8_t in[32]) {
- out[0] = *((const uint64_t *)&in[0]);
- out[1] = *((const uint64_t *)&in[8]);
- out[2] = *((const uint64_t *)&in[16]);
- out[3] = *((const uint64_t *)&in[24]);
+ out[0] = load_u64(&in[0]);
+ out[1] = load_u64(&in[8]);
+ out[2] = load_u64(&in[16]);
+ out[3] = load_u64(&in[24]);
}
/* smallfelem_to_bin32 takes a smallfelem and serialises into a little endian,
* 32 byte array. This assumes that the CPU is little-endian. */
static void smallfelem_to_bin32(uint8_t out[32], const smallfelem in) {
- *((uint64_t *)&out[0]) = in[0];
- *((uint64_t *)&out[8]) = in[1];
- *((uint64_t *)&out[16]) = in[2];
- *((uint64_t *)&out[24]) = in[3];
+ store_u64(&out[0], in[0]);
+ store_u64(&out[8], in[1]);
+ store_u64(&out[16], in[2]);
+ store_u64(&out[24], in[3]);
}
/* To preserve endianness when using BN_bn2bin and BN_bin2bn. */
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index cf2474a4..b2eb6189 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -42,25 +42,3 @@ add_library(
v3_sxnet.c
v3_utl.c
)
-
-add_executable(
- v3name_test
-
- v3name_test.c
-
- $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(v3name_test crypto)
-add_dependencies(all_tests v3name_test)
-
-add_executable(
- tab_test
-
- tab_test.c
-
- $<TARGET_OBJECTS:test_support>
-)
-
-target_link_libraries(tab_test crypto)
-add_dependencies(all_tests tab_test)
diff --git a/src/crypto/x509v3/ext_dat.h b/src/crypto/x509v3/ext_dat.h
index 9ece19c5..78fa7936 100644
--- a/src/crypto/x509v3/ext_dat.h
+++ b/src/crypto/x509v3/ext_dat.h
@@ -56,6 +56,10 @@
/* This file contains a table of "standard" extensions */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
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;
@@ -133,3 +137,7 @@ static const X509V3_EXT_METHOD *const standard_exts[] = {
/* Number of standard extensions */
#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *))
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
diff --git a/src/crypto/x509v3/tab_test.c b/src/crypto/x509v3/tab_test.cc
index 19005474..bf91a265 100644
--- a/src/crypto/x509v3/tab_test.c
+++ b/src/crypto/x509v3/tab_test.cc
@@ -57,52 +57,22 @@
*
*/
-/*
- * Simple program to check the ext_dat.h is correct and print out problems if
- * it is not.
- */
+#if !defined(BORINGSSL_SHARED_LIBRARY)
-#include <stdio.h>
+#include <gtest/gtest.h>
-#include <openssl/base.h>
-#include <openssl/crypto.h>
-#include <openssl/obj.h>
#include <openssl/x509v3.h>
-#if !defined(BORINGSSL_SHARED_LIBRARY)
-# include "ext_dat.h"
-#endif
+#include "../internal.h"
+#include "ext_dat.h"
-int main(void)
-{
-#if !defined(BORINGSSL_SHARED_LIBRARY)
- unsigned i;
- int prev = -1, bad = 0;
- const X509V3_EXT_METHOD *const *tmp;
- CRYPTO_library_init();
- i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *);
- if (i != STANDARD_EXTENSION_COUNT)
- fprintf(stderr, "Extension number invalid expecting %d\n", i);
- tmp = standard_exts;
- for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) {
- if ((*tmp)->ext_nid < prev)
- bad = 1;
- prev = (*tmp)->ext_nid;
-
- }
- if (bad) {
- tmp = standard_exts;
- fprintf(stderr, "Extensions out of order!\n");
- for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++)
- printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid));
- return 1;
- } else {
- printf("PASS\n");
- return 0;
- }
-#else
- /* TODO(davidben): Fix this test in the shared library build. */
- printf("PASS\n");
- return 0;
-#endif
+// Check ext_data.h is correct.
+TEST(X509V3Test, TabTest) {
+ EXPECT_EQ(OPENSSL_ARRAY_SIZE(standard_exts), STANDARD_EXTENSION_COUNT);
+ for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(standard_exts); i++) {
+ SCOPED_TRACE(i);
+ EXPECT_LT(standard_exts[i-1]->ext_nid, standard_exts[i]->ext_nid);
+ }
}
+
+#endif // !BORINGSSL_SHARED_LIBRARY
diff --git a/src/crypto/x509v3/v3name_test.c b/src/crypto/x509v3/v3name_test.cc
index 959b924d..0736120f 100644
--- a/src/crypto/x509v3/v3name_test.c
+++ b/src/crypto/x509v3/v3name_test.cc
@@ -57,6 +57,8 @@
#include <stdarg.h>
#include <string.h>
+#include <gtest/gtest.h>
+
#include <openssl/crypto.h>
#include <openssl/mem.h>
#include <openssl/x509.h>
@@ -335,7 +337,7 @@ static void run_cert(X509 *crt, const char *nameincert,
while (*pname) {
int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0;
size_t namelen = strlen(*pname);
- char *name = malloc(namelen);
+ char *name = (char *)malloc(namelen);
int match, ret;
OPENSSL_memcpy(name, *pname, namelen);
@@ -383,31 +385,19 @@ static void run_cert(X509 *crt, const char *nameincert,
}
}
-int main(void)
-{
- CRYPTO_library_init();
-
+// TOOD(davidben): Convert this test to GTest more thoroughly.
+TEST(X509V3Test, NameTest) {
const struct set_name_fn *pfn = name_fns;
while (pfn->name) {
const char *const *pname = names;
while (*pname) {
- X509 *crt = make_cert();
- if (crt == NULL) {
- fprintf(stderr, "make_cert failed\n");
- return 1;
- }
- if (!pfn->fn(crt, *pname)) {
- fprintf(stderr, "X509 name setting failed\n");
- return 1;
- }
- run_cert(crt, *pname, pfn);
- X509_free(crt);
+ bssl::UniquePtr<X509> crt(make_cert());
+ ASSERT_TRUE(crt);
+ ASSERT_TRUE(pfn->fn(crt.get(), *pname));
+ run_cert(crt.get(), *pname, pfn);
++pname;
}
++pfn;
}
- if (errors == 0) {
- printf("PASS\n");
- }
- return errors > 0 ? 1 : 0;
+ EXPECT_EQ(0, errors);
}