Files
cli/vendor/aws-lc-sys/aws-lc/crypto/endian_test.cc

326 lines
9.7 KiB
C++

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC
#include <gtest/gtest.h>
#include "internal.h"
#include "openssl/aes.h"
#include "openssl/bn.h"
#include "test/test_util.h"
TEST(EndianTest, u16Operations) {
uint8_t buffer[2];
uint16_t val = 0x1234;
uint8_t expected_be[2] = {0x12, 0x34};
uint8_t expected_le[2] = {0x34, 0x12};
CRYPTO_store_u16_le(buffer, val);
EXPECT_EQ(Bytes(expected_le), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_u16_le(buffer));
CRYPTO_store_u16_be(buffer, val);
EXPECT_EQ(Bytes(expected_be), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_u16_be(buffer));
}
TEST(EndianTest, u32Operations) {
uint8_t buffer[4];
uint32_t val = 0x12345678;
uint8_t expected_be[4] = {0x12, 0x34, 0x56, 0x78};
uint8_t expected_le[4] = {0x78, 0x56, 0x34, 0x12};
CRYPTO_store_u32_le(buffer, val);
EXPECT_EQ(Bytes(expected_le), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_u32_le(buffer));
CRYPTO_store_u32_be(buffer, val);
EXPECT_EQ(Bytes(expected_be), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_u32_be(buffer));
}
TEST(EndianTest, u64Operations) {
uint8_t buffer[8];
uint64_t val = 0x123456789abcdef0;
uint8_t expected_be[8] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
uint8_t expected_le[8] = {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12};
CRYPTO_store_u64_le(buffer, val);
EXPECT_EQ(Bytes(expected_le), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_u64_le(buffer));
CRYPTO_store_u64_be(buffer, val);
EXPECT_EQ(Bytes(expected_be), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_u64_be(buffer));
}
TEST(EndianTest, wordOperations) {
uint8_t buffer[sizeof(crypto_word_t)];
#if defined(OPENSSL_64_BIT)
size_t val = 0x123456789abcdef0;
uint8_t expected_le[8] = {0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12};
#else
size_t val = 0x12345678;
uint8_t expected_le[4] = {0x78, 0x56, 0x34, 0x12};
#endif
CRYPTO_store_word_le(buffer, val);
EXPECT_EQ(Bytes(expected_le), Bytes(buffer));
EXPECT_EQ(val, CRYPTO_load_word_le(buffer));
}
TEST(EndianTest, TestRotate32) {
uint32_t value = 0b00000010000000000000000000000;
uint32_t expected = 0b00100000000000000000000000000;
uint32_t rotl_by = 4;
uint32_t rotr_by = 32 - rotl_by;
uint32_t rotl_value = CRYPTO_rotl_u32(value, rotl_by);
uint32_t rotr_value = CRYPTO_rotr_u32(value, rotr_by);
ASSERT_EQ(rotl_value, rotr_value);
EXPECT_EQ(expected, rotl_value);
ASSERT_EQ(CRYPTO_rotr_u32(rotl_value, rotl_by), value);
}
TEST(EndianTest, TestRotate64) {
uint64_t value = 0b0000001000000000000000000000000000010000000000000000000000;
uint64_t expected = 0b0010000000000000000000000000000100000000000000000000000000;
uint64_t rotl_by = 4;
uint64_t rotr_by = 64 - rotl_by;
uint64_t rotl_value = CRYPTO_rotl_u64(value, rotl_by);
uint64_t rotr_value = CRYPTO_rotr_u64(value, rotr_by);
ASSERT_EQ(rotl_value, rotr_value);
EXPECT_EQ(expected, rotl_value);
ASSERT_EQ(CRYPTO_rotr_u64(rotl_value, rotl_by), value);
}
union test_union {
uint16_t big[2];
uint8_t small[4];
};
struct test_struct {
test_union union_val;
};
TEST(EndianTest, TestStructUnion) {
struct test_struct val = {{{0}}};
val.union_val.big[0] = 0x1234;
val.union_val.big[1] = 0x5678;
#if defined(OPENSSL_BIG_ENDIAN)
ASSERT_EQ(val.union_val.small[0], 0x12);
ASSERT_EQ(val.union_val.small[1], 0x34);
ASSERT_EQ(val.union_val.small[2], 0x56);
ASSERT_EQ(val.union_val.small[3], 0x78);
#else
ASSERT_EQ(val.union_val.small[0], 0x34);
ASSERT_EQ(val.union_val.small[1], 0x12);
ASSERT_EQ(val.union_val.small[2], 0x78);
ASSERT_EQ(val.union_val.small[3], 0x56);
#endif
}
// Shift left is increasing value/significance
// shift right decreases value/drops values
TEST(EndianTest, Shifting) {
uint32_t test = 0b1010000000010001;
ASSERT_EQ(test << 4, (uint32_t)0b10100000000100010000);
ASSERT_EQ(test >> 4, (uint32_t)0b101000000001);
}
TEST(EndianTest, Swap) {
EXPECT_EQ(0x3412, CRYPTO_bswap2(0x1234));
EXPECT_EQ((uint32_t)0x78563412, CRYPTO_bswap4(0x12345678));
EXPECT_EQ(0xf0debc9a78563412, CRYPTO_bswap8(0x123456789abcdef0));
}
TEST(EndianTest, BN_bin2bn) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[256];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[254] = 0x01;
input[255] = 0x02;
ASSERT_NE(nullptr, BN_bin2bn(input, sizeof(input), x.get()));
EXPECT_FALSE(BN_is_zero(x.get()));
for (size_t i = 1; i < (sizeof(input)*8/BN_BITS2) - 1; i++) {
SCOPED_TRACE(i);
EXPECT_EQ((uint64_t)0, x.get()->d[i]);
}
EXPECT_EQ((uint64_t)0x0102, x.get()->d[0]);
EXPECT_EQ((uint64_t)0xaa01 << (BN_BITS2-16), x.get()->d[(256*8/BN_BITS2)-1]);
}
TEST(EndianTest, BN_le2bn) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[256];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[254] = 0x01;
input[255] = 0x02;
ASSERT_NE(nullptr, BN_le2bn(input, sizeof(input), x.get()));
EXPECT_FALSE(BN_is_zero(x.get()));
for (int i = 1; i < (256*8/BN_BITS2) - 1; i++) {
SCOPED_TRACE(i);
EXPECT_EQ((uint64_t)0, x.get()->d[i]);
}
EXPECT_EQ((uint64_t)0x01aa, x.get()->d[0]);
EXPECT_EQ((uint64_t)0x0201 << (BN_BITS2-16), x.get()->d[(256*8/BN_BITS2)-1]);
}
// This test creates a BIGNUM, where 255 bytes are significant.
// Notice that 255 = 7 (mod 8) and 255 = 3 (mod 4), so the most significant
// bytes do not fill an entire word in the output BIGNUM, requiring special
// handling in the underlying logic.
TEST(EndianTest, BN_le2bn_255) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[255];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[254] = 0x01;
ASSERT_TRUE(BN_le2bn(input, sizeof(input), x.get()));
EXPECT_FALSE(BN_is_zero(x.get()));
for (size_t i = 1; i <= (255/sizeof(BN_ULONG)) - 1; i++) {
EXPECT_EQ((BN_ULONG)0, x.get()->d[i]);
}
EXPECT_EQ((BN_ULONG)0x01aa, x.get()->d[0]);
EXPECT_EQ((BN_ULONG)0x01 << (BN_BITS2-16), x.get()->d[255/sizeof(BN_ULONG)]);
}
TEST(EndianTest, BN_bn2bin) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[256];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[254] = 0x01;
input[255] = 0x02;
ASSERT_NE(nullptr, BN_bin2bn(input, sizeof(input), x.get()));
uint8_t out[256];
OPENSSL_memset(out, 0, sizeof(out));
EXPECT_EQ((size_t)256, BN_bn2bin(x.get(), out));
EXPECT_EQ(Bytes(input), Bytes(out));
}
TEST(EndianTest, BN_bn2le_padded) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[256];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[254] = 0x01;
input[255] = 0x02;
ASSERT_NE(nullptr, BN_le2bn(input, sizeof(input), x.get()));
uint8_t out[256];
OPENSSL_memset(out, 0, sizeof(out));
EXPECT_EQ(1, BN_bn2le_padded(out, sizeof(out), x.get()));
EXPECT_EQ(Bytes(input), Bytes(out));
}
// This test creates a BIGNUM, where 255 bytes are significant.
// It then calls |BN_bn2le_padded| to write the number into a 255-byte array
// in little-endian byte-order.
// Notice that 255 = 7 (mod 8) and 255 = 3 (mod 4), so the output array does not
// have room to hold every word of the input, requiring special handling
// in the underlying logic.
TEST(EndianTest, BN_bn2le_padded_255) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[255];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[253] = 0x01;
input[254] = 0x01;
ASSERT_TRUE(BN_le2bn(input, sizeof(input), x.get()));
uint8_t out[255];
OPENSSL_memset(out, 0, sizeof(out));
EXPECT_EQ(1, BN_bn2le_padded(out, sizeof(out), x.get()));
EXPECT_EQ(Bytes(input), Bytes(out));
}
// This test creates a 256-byte BIGNUM, where only 2 bytes are significant.
// It then calls |BN_bn2le_padded| to write the number into a 2-byte array
// in little-endian byte-order.
TEST(EndianTest, BN_bn2le_padded_much) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[256];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
ASSERT_TRUE(BN_le2bn(input, sizeof(input), x.get()));
uint8_t out[2];
OPENSSL_memset(out, 0, sizeof(out));
EXPECT_EQ(1, BN_bn2le_padded(out, sizeof(out), x.get()));
EXPECT_EQ(Bytes(input, 2), Bytes(out, 2));
}
TEST(EndianTest, BN_bn2bin_padded) {
bssl::UniquePtr<BIGNUM> x(BN_new());
uint8_t input[256];
OPENSSL_memset(input, 0, sizeof(input));
input[0] = 0xaa;
input[1] = 0x01;
input[254] = 0x01;
input[255] = 0x02;
ASSERT_NE(nullptr, BN_bin2bn(input, sizeof(input), x.get()));
uint8_t out[256];
OPENSSL_memset(out, 0, sizeof(out));
EXPECT_EQ(1, BN_bn2bin_padded(out, sizeof(out), x.get()));
EXPECT_EQ(Bytes(input), Bytes(out));
}
TEST(EndianTest, AES) {
// Initialize the key and message buffers with zeros
uint8_t key[16] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33,
0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x50};
uint8_t message[AES_BLOCK_SIZE] = {0x50, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
// Allocate buffer to store the encrypted message
uint8_t encrypted_message[AES_BLOCK_SIZE];
// Create an AES_KEY struct
AES_KEY aes_key = {{0}, 0};
ASSERT_EQ(0, AES_set_encrypt_key(key, 128, &aes_key));
AES_encrypt(message, encrypted_message, &aes_key);
const uint8_t known_value_bytes[AES_BLOCK_SIZE] = {
0x5e, 0x3e, 0x8e, 0x76, 0xf4, 0xf2, 0x7d, 0x41, 0x35, 0x86, 0x96, 0xb5, 0x57, 0x2d, 0xd5, 0xc6
};
EXPECT_EQ(Bytes(known_value_bytes), Bytes(encrypted_message));
}
TEST(EndianTest, memcpy) {
uint8_t buffer[2] = {0xab, 0xcd};
uint16_t out = 0;
memcpy(&out, buffer, 2);
#if defined(OPENSSL_BIG_ENDIAN)
EXPECT_EQ(out, 0xabcd);
#else
EXPECT_EQ(out, 0xcdab);
#endif
}
TEST(EndianTest, masking) {
uint16_t value = 0xabcd;
uint16_t mask = 0xf00f;
uint16_t result = value & mask;
EXPECT_EQ(result, 0xa00d);
}