mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 12:28:09 +00:00
feat(crypto): add big endian support
This commit is contained in:
parent
428caf3d35
commit
684e0c886d
@ -1,20 +1,39 @@
|
||||
|
||||
#include "byte_order.h"
|
||||
|
||||
static inline uint32_t load32(const void *src) {
|
||||
uint32_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
REVERSE32(w, w);
|
||||
#endif
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline uint64_t load64(const void *src) {
|
||||
uint64_t w;
|
||||
memcpy(&w, src, sizeof w);
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
REVERSE64(w, w);
|
||||
#endif
|
||||
return w;
|
||||
}
|
||||
|
||||
static inline void store16(void *dst, uint16_t w) { memcpy(dst, &w, sizeof w); }
|
||||
|
||||
static inline void store32(void *dst, uint32_t w) { memcpy(dst, &w, sizeof w); }
|
||||
static inline void store32(void *dst, uint32_t w) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
REVERSE32(w, w);
|
||||
#endif
|
||||
memcpy(dst, &w, sizeof w);
|
||||
}
|
||||
|
||||
static inline void store64(void *dst, uint64_t w) { memcpy(dst, &w, sizeof w); }
|
||||
static inline void store64(void *dst, uint64_t w) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
REVERSE64(w, w);
|
||||
#endif
|
||||
memcpy(dst, &w, sizeof w);
|
||||
}
|
||||
|
||||
static inline uint32_t rotr32(const uint32_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (32 - c));
|
||||
|
59
crypto/byte_order.h
Normal file
59
crypto/byte_order.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef __BYTE_ORDER_H__
|
||||
#define __BYTE_ORDER_H__
|
||||
|
||||
// FROM sha2.h:
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivalent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
|
||||
#ifndef LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#endif
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#define REVERSE32(w, x) \
|
||||
{ \
|
||||
uint32_t tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
|
||||
}
|
||||
|
||||
#define REVERSE64(w, x) \
|
||||
{ \
|
||||
uint64_t tmp = (w); \
|
||||
tmp = (tmp >> 32) | (tmp << 32); \
|
||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
|
||||
#endif
|
@ -36,6 +36,7 @@
|
||||
#include "int-util.h"
|
||||
#include "sha2.h"
|
||||
#include "../base58.h"
|
||||
#include "../byte_order.h"
|
||||
|
||||
const size_t alphabet_size = 58; // sizeof(b58digits_ordered) - 1;
|
||||
const size_t encoded_block_sizes[] = {0, 2, 3, 5, 6, 7, 9, 10, 11};
|
||||
@ -71,7 +72,11 @@ void uint_64_to_8be(uint64_t num, size_t size, uint8_t* data)
|
||||
{
|
||||
assert(1 <= size && size <= sizeof(uint64_t));
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
uint64_t num_be = SWAP64(num);
|
||||
#else
|
||||
uint64_t num_be = num;
|
||||
#endif
|
||||
memcpy(data, (uint8_t*)(&num_be) + sizeof(uint64_t) - size, size);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
#include "xmr.h"
|
||||
#include "../byte_order.h"
|
||||
#include "int-util.h"
|
||||
#include "rand.h"
|
||||
#include "serialize.h"
|
||||
@ -128,6 +129,12 @@ void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major,
|
||||
char data[sizeof(prefix) + sizeof(buff) + 2 * sizeof(uint32_t)] = {0};
|
||||
memcpy(data, prefix, sizeof(prefix));
|
||||
memcpy(data + sizeof(prefix), buff, sizeof(buff));
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
REVERSE32(major, major);
|
||||
REVERSE32(minor, minor);
|
||||
#endif
|
||||
|
||||
memcpy(data + sizeof(prefix) + sizeof(buff), &major, sizeof(uint32_t));
|
||||
memcpy(data + sizeof(prefix) + sizeof(buff) + sizeof(uint32_t), &minor,
|
||||
sizeof(uint32_t));
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <stdint.h>
|
||||
#include "sha2.h"
|
||||
#include "memzero.h"
|
||||
#include "byte_order.h"
|
||||
|
||||
/*
|
||||
* ASSERT NOTE:
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "byte_order.h"
|
||||
|
||||
#define SHA1_BLOCK_LENGTH 64
|
||||
#define SHA1_DIGEST_LENGTH 20
|
||||
@ -60,32 +61,6 @@ typedef struct _SHA512_CTX {
|
||||
uint64_t buffer[SHA512_BLOCK_LENGTH/sizeof(uint64_t)];
|
||||
} SHA512_CTX;
|
||||
|
||||
/*** ENDIAN REVERSAL MACROS *******************************************/
|
||||
#ifndef LITTLE_ENDIAN
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#endif
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define REVERSE32(w,x) { \
|
||||
uint32_t tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
|
||||
}
|
||||
#define REVERSE64(w,x) { \
|
||||
uint64_t tmp = (w); \
|
||||
tmp = (tmp >> 32) | (tmp << 32); \
|
||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
extern const uint32_t sha256_initial_hash_value[8];
|
||||
extern const uint64_t sha512_initial_hash_value[8];
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "sha3.h"
|
||||
#include "memzero.h"
|
||||
#include "byte_order.h"
|
||||
|
||||
#define I64(x) x##LL
|
||||
#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
|
||||
@ -165,6 +166,13 @@ static void keccak_chi(uint64_t *A)
|
||||
|
||||
static void sha3_permutation(uint64_t *state)
|
||||
{
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
int i;
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
REVERSE64(state[i], state[i]);
|
||||
}
|
||||
#endif
|
||||
int round = 0;
|
||||
for (round = 0; round < NumberOfRounds; round++)
|
||||
{
|
||||
@ -202,6 +210,12 @@ static void sha3_permutation(uint64_t *state)
|
||||
/* apply iota(state, round) */
|
||||
*state ^= keccak_round_constants[round];
|
||||
}
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
for (i = 0; i < 25; i++)
|
||||
{
|
||||
REVERSE64(state[i], state[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4823,6 +4823,60 @@ START_TEST(test_blake2b) {
|
||||
}
|
||||
END_TEST
|
||||
|
||||
// Blake2b-256 personalized, a la ZCash
|
||||
// Test vectors from https://zips.z.cash/zip-0243
|
||||
START_TEST(test_blake2bp) {
|
||||
static const struct {
|
||||
const char *msg;
|
||||
const char *personal;
|
||||
const char *hash;
|
||||
} tests[] = {
|
||||
{
|
||||
"",
|
||||
"ZcashPrevoutHash",
|
||||
"d53a633bbecf82fe9e9484d8a0e727c73bb9e68c96e72dec30144f6a84afa136",
|
||||
},
|
||||
{
|
||||
"",
|
||||
"ZcashSequencHash",
|
||||
"a5f25f01959361ee6eb56a7401210ee268226f6ce764a4f10b7f29e54db37272",
|
||||
|
||||
},
|
||||
{
|
||||
"e7719811893e0000095200ac6551ac636565b2835a0805750200025151",
|
||||
"ZcashOutputsHash",
|
||||
"ab6f7f6c5ad6b56357b5f37e16981723db6c32411753e28c175e15589172194a",
|
||||
},
|
||||
{
|
||||
"0bbe32a598c22adfb48cef72ba5d4287c0cefbacfd8ce195b4963c34a94bba7a1"
|
||||
"75dae4b090f47a068e227433f9e49d3aa09e356d8d66d0c0121e91a3c4aa3f27fa1b"
|
||||
"63396e2b41d",
|
||||
"ZcashPrevoutHash",
|
||||
"cacf0f5210cce5fa65a59f314292b3111d299e7d9d582753cf61e1e408552ae4",
|
||||
}};
|
||||
|
||||
uint8_t digest[32];
|
||||
for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) {
|
||||
size_t msg_len = strlen(tests[i].msg) / 2;
|
||||
|
||||
// Test progressive hashing.
|
||||
size_t part_len = msg_len / 2;
|
||||
BLAKE2B_CTX ctx;
|
||||
ck_assert_int_eq(
|
||||
blake2b_InitPersonal(&ctx, sizeof(digest), tests[i].personal,
|
||||
strlen(tests[i].personal)),
|
||||
0);
|
||||
ck_assert_int_eq(blake2b_Update(&ctx, fromhex(tests[i].msg), part_len), 0);
|
||||
ck_assert_int_eq(blake2b_Update(&ctx, NULL, 0), 0);
|
||||
ck_assert_int_eq(blake2b_Update(&ctx, fromhex(tests[i].msg) + part_len,
|
||||
msg_len - part_len),
|
||||
0);
|
||||
ck_assert_int_eq(blake2b_Final(&ctx, digest, sizeof(digest)), 0);
|
||||
ck_assert_mem_eq(digest, fromhex(tests[i].hash), sizeof(digest));
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
// test vectors from
|
||||
// https://raw.githubusercontent.com/BLAKE2/BLAKE2/master/testvectors/blake2s-kat.txt
|
||||
START_TEST(test_blake2s) {
|
||||
@ -5530,7 +5584,7 @@ START_TEST(test_slip39_word_index) {
|
||||
// 9999 value is never checked since the word is not in list
|
||||
{"fakeword", false, 9999}};
|
||||
for (size_t i = 0; i < (sizeof(vectors) / sizeof(*vectors)); i++) {
|
||||
bool result = word_index(&index, vectors[i].word, sizeof(vectors[i].word));
|
||||
bool result = word_index(&index, vectors[i].word, strlen(vectors[i].word));
|
||||
ck_assert_int_eq(result, vectors[i].expected_result);
|
||||
if (result) {
|
||||
ck_assert_uint_eq(index, vectors[i].expected_index);
|
||||
@ -9469,6 +9523,7 @@ Suite *test_suite(void) {
|
||||
|
||||
tc = tcase_create("blake2");
|
||||
tcase_add_test(tc, test_blake2b);
|
||||
tcase_add_test(tc, test_blake2bp);
|
||||
tcase_add_test(tc, test_blake2s);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user