Cleanup, adjust derivation API to API level 5, adjust linker script and NVRAM location, move to internal SHA3 API, fix address checksum
This commit is contained in:
parent
4a1dfa0c8b
commit
0eb82c6f98
|
@ -18,6 +18,7 @@
|
|||
APPNAME = Ethereum
|
||||
TARGET_ID = 0x31100002 #Nano S
|
||||
#TARGET_ID = 0x31000002 #Blue
|
||||
APP_LOAD_PARAMS=--appFlags 0x40 --path "44'/60'" --path "44'/61'" --curve secp256k1
|
||||
|
||||
|
||||
################
|
||||
|
@ -44,9 +45,9 @@ PROG := token-genericwallet
|
|||
|
||||
CONFIG_PRODUCTIONS := bin/$(PROG)
|
||||
|
||||
SOURCE_PATH := src_genericwallet $(BOLOS_SDK)/src $(dir $(shell find $(BOLOS_SDK)/lib_stusb* | grep "\.c$$")) src_common src_tmp
|
||||
SOURCE_PATH := src_genericwallet $(BOLOS_SDK)/src $(dir $(shell find $(BOLOS_SDK)/lib_stusb* | grep "\.c$$")) src_common
|
||||
SOURCE_FILES := $(foreach path, $(SOURCE_PATH),$(shell find $(path) | grep "\.c$$") )
|
||||
INCLUDES_PATH := $(dir $(shell find $(BOLOS_SDK)/lib_stusb* | grep "\.h$$")) include src_genericwallet $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm src_common src_tmp
|
||||
INCLUDES_PATH := $(dir $(shell find $(BOLOS_SDK)/lib_stusb* | grep "\.h$$")) include src_genericwallet $(BOLOS_SDK)/include $(BOLOS_SDK)/include/arm src_common
|
||||
|
||||
### platform definitions
|
||||
DEFINES := ST31 gcc __IO=volatile
|
||||
|
@ -64,9 +65,9 @@ CC := $(CLANGPATH)/clang
|
|||
|
||||
CFLAGS :=
|
||||
CFLAGS += -gdwarf-2 -gstrict-dwarf
|
||||
CFLAGS += -O0
|
||||
#CFLAGS += -O0
|
||||
#CFLAGS += -O0 -g3
|
||||
#CFLAGS += -O3 -Os
|
||||
CFLAGS += -O3 -Os
|
||||
CFLAGS += -mcpu=cortex-m0 -mthumb
|
||||
CFLAGS += -fno-common -mtune=cortex-m0 -mlittle-endian
|
||||
CFLAGS += -std=gnu99 -Werror=int-to-pointer-cast -Wall -Wextra #-save-temps
|
||||
|
@ -94,7 +95,7 @@ LDFLAGS += -fno-common -ffunction-sections -fdata-sections -fwhole-program -nos
|
|||
LDFLAGS += -mno-unaligned-access
|
||||
#LDFLAGS += -nodefaultlibs
|
||||
#LDFLAGS += -nostdlib -nostdinc
|
||||
LDFLAGS += -Tscript.ld -Wl,--gc-sections -Wl,-Map,debug/$(PROG).map,--cref
|
||||
LDFLAGS += -T$(BOLOS_SDK)/script.ld -Wl,--gc-sections -Wl,-Map,debug/$(PROG).map,--cref
|
||||
LDLIBS += -Wl,--library-path -Wl,$(GCCPATH)/../lib/armv6-m/
|
||||
#LDLIBS += -Wl,--start-group
|
||||
LDLIBS += -lm -lgcc -lc
|
||||
|
@ -124,16 +125,16 @@ log = $(if $(strip $(VERBOSE)),$1,@$1)
|
|||
|
||||
default: prepare bin/$(PROG)
|
||||
|
||||
load:
|
||||
python -m ledgerblue.loadApp --targetId $(TARGET_ID) --appFlags 0xc0 --fileName bin/$(PROG).hex --appName $(APPNAME) --icon `python $(BOLOS_SDK)/icon.py 16 16 icon.gif hexbitmaponly` --path "44'/60'"
|
||||
load:
|
||||
python -m ledgerblue.loadApp --targetId $(TARGET_ID) --fileName bin/$(PROG).hex --appName $(APPNAME) --icon `python $(BOLOS_SDK)/icon.py 16 16 icon.gif hexbitmaponly` $(APP_LOAD_PARAMS)
|
||||
|
||||
load_release:
|
||||
python -m ledgerblue.loadApp --targetId $(TARGET_ID) --appFlags 0xc0 --fileName bin/$(PROG).hex --appName $(APPNAME) --icon `python $(BOLOS_SDK)/icon.py 16 16 icon.gif hexbitmaponly` --path "44'/60'" --signature 3044022061a619a509c9ab16b933b9f509f6d01958aa042467700d6680c8568f8aa5ede5022063c599da68037a233feeb591922e156035f70fed667b051a954cdb68f8881ef4
|
||||
python -m ledgerblue.loadApp --targetId $(TARGET_ID) --fileName bin/$(PROG).hex --appName $(APPNAME) --icon `python $(BOLOS_SDK)/icon.py 16 16 icon.gif hexbitmaponly` $(APP_LOAD_PARAMS) --signature 3044022065e5bcf6519ea12ff991e429cc85bf7ecc789bd1a7a141d5e2dc358e5544c6170220726801803361b3296b83a3d14be8afc3374bda215b4dadd3d67bc3518e1f78bc
|
||||
|
||||
delete:
|
||||
python -m ledgerblue.deleteApp --targetId $(TARGET_ID) --appName $(APPNAME)
|
||||
|
||||
bin/$(PROG): $(OBJECT_FILES) script.ld
|
||||
bin/$(PROG): $(OBJECT_FILES) $(BOLOS_SDK)/script.ld
|
||||
@echo "[LINK] $@"
|
||||
$(call log,$(call link_cmdline,$(OBJECT_FILES) $(LDLIBS),$@))
|
||||
$(call log,$(GCCPATH)/arm-none-eabi-objcopy -O ihex -S bin/$(PROG) bin/$(PROG).hex)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#define MAX_INT256 32
|
||||
#define MAX_ADDRESS 20
|
||||
|
||||
void initTx(txContext_t *context, app_cx_sha3_t *sha3, txContent_t *content,
|
||||
void initTx(txContext_t *context, cx_sha3_t *sha3, txContent_t *content,
|
||||
ustreamProcess_t customProcessor, void *extra) {
|
||||
os_memset(context, 0, sizeof(txContext_t));
|
||||
context->sha3 = sha3;
|
||||
|
@ -29,7 +29,7 @@ void initTx(txContext_t *context, app_cx_sha3_t *sha3, txContent_t *content,
|
|||
context->customProcessor = customProcessor;
|
||||
context->extra = extra;
|
||||
context->currentField = TX_RLP_CONTENT;
|
||||
app_cx_sha3_init(context->sha3, 256);
|
||||
cx_keccak_init(context->sha3, 256);
|
||||
}
|
||||
|
||||
uint8_t readTxByte(txContext_t *context) {
|
||||
|
@ -45,7 +45,7 @@ uint8_t readTxByte(txContext_t *context) {
|
|||
context->currentFieldPos++;
|
||||
}
|
||||
if (!(context->processingField && context->fieldSingleByte)) {
|
||||
app_cx_hash((cx_hash_t *)context->sha3, 0, &data, 1, NULL);
|
||||
cx_hash((cx_hash_t *)context->sha3, 0, &data, 1, NULL);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
@ -59,8 +59,8 @@ void copyTxData(txContext_t *context, uint8_t *out, uint32_t length) {
|
|||
os_memmove(out, context->workBuffer, length);
|
||||
}
|
||||
if (!(context->processingField && context->fieldSingleByte)) {
|
||||
app_cx_hash((cx_hash_t *)context->sha3, 0, context->workBuffer, length,
|
||||
NULL);
|
||||
cx_hash((cx_hash_t *)context->sha3, 0, context->workBuffer, length,
|
||||
NULL);
|
||||
}
|
||||
context->workBuffer += length;
|
||||
context->commandLength -= length;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include <stdbool.h>
|
||||
#include "app_cx_sha3.h"
|
||||
|
||||
struct txContext_t;
|
||||
|
||||
|
@ -56,7 +55,7 @@ typedef struct txContent_t {
|
|||
|
||||
typedef struct txContext_t {
|
||||
rlpTxField_e currentField;
|
||||
app_cx_sha3_t *sha3;
|
||||
cx_sha3_t *sha3;
|
||||
uint32_t currentFieldLength;
|
||||
uint32_t currentFieldPos;
|
||||
bool currentFieldIsList;
|
||||
|
@ -72,7 +71,7 @@ typedef struct txContext_t {
|
|||
void *extra;
|
||||
} txContext_t;
|
||||
|
||||
void initTx(txContext_t *context, app_cx_sha3_t *sha3, txContent_t *content,
|
||||
void initTx(txContext_t *context, cx_sha3_t *sha3, txContent_t *content,
|
||||
ustreamProcess_t customProcessor, void *extra);
|
||||
parserStatus_e processTx(txContext_t *context, uint8_t *buffer,
|
||||
uint32_t length);
|
||||
|
|
|
@ -115,18 +115,18 @@ bool rlpDecodeLength(uint8_t *buffer, uint32_t bufferLength,
|
|||
}
|
||||
|
||||
void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context) {
|
||||
cx_sha3_t *sha3Context) {
|
||||
uint8_t hashAddress[32];
|
||||
app_cx_sha3_init(sha3Context, 256);
|
||||
app_cx_hash((cx_hash_t *)sha3Context, CX_LAST, publicKey->W + 1, 64,
|
||||
hashAddress);
|
||||
cx_keccak_init(sha3Context, 256);
|
||||
cx_hash((cx_hash_t *)sha3Context, CX_LAST, publicKey->W + 1, 64,
|
||||
hashAddress);
|
||||
os_memmove(out, hashAddress + 12, 20);
|
||||
}
|
||||
|
||||
static const uint8_t const HEXDIGITS[] = "0123456789ABCDEF";
|
||||
|
||||
#ifdef CHECKSUM_1
|
||||
|
||||
static const uint8_t const HEXDIGITS[] = "0123456789ABCDEF";
|
||||
|
||||
static const uint8_t const MASK[] = {0x80, 0x40, 0x20, 0x10,
|
||||
0x08, 0x04, 0x02, 0x01};
|
||||
|
||||
|
@ -150,20 +150,20 @@ char convertDigit(uint8_t *address, uint8_t index, uint8_t *hash) {
|
|||
}
|
||||
|
||||
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context) {
|
||||
cx_sha3_t *sha3Context) {
|
||||
uint8_t hashAddress[32];
|
||||
app_cx_sha3_init(sha3Context, 256);
|
||||
app_cx_hash((cx_hash_t *)sha3Context, CX_LAST, publicKey->W + 1, 64,
|
||||
hashAddress);
|
||||
cx_keccak_init(sha3Context, 256);
|
||||
cx_hash((cx_hash_t *)sha3Context, CX_LAST, publicKey->W + 1, 64,
|
||||
hashAddress);
|
||||
getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context);
|
||||
}
|
||||
|
||||
void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context) {
|
||||
cx_sha3_t *sha3Context) {
|
||||
uint8_t hashChecksum[32];
|
||||
uint8_t i;
|
||||
app_cx_sha3_init(sha3Context, 256);
|
||||
app_cx_hash((cx_hash_t *)sha3Context, CX_LAST, address, 20, hashChecksum);
|
||||
cx_keccak_init(sha3Context, 256);
|
||||
cx_hash((cx_hash_t *)sha3Context, CX_LAST, address, 20, hashChecksum);
|
||||
for (i = 0; i < 40; i++) {
|
||||
out[i] = convertDigit(address, i, hashChecksum);
|
||||
}
|
||||
|
@ -172,17 +172,19 @@ void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
|||
|
||||
#else
|
||||
|
||||
static const uint8_t const HEXDIGITS[] = "0123456789abcdef";
|
||||
|
||||
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context) {
|
||||
cx_sha3_t *sha3Context) {
|
||||
uint8_t hashAddress[32];
|
||||
app_cx_sha3_init(sha3Context, 256);
|
||||
app_cx_hash((cx_hash_t *)sha3Context, CX_LAST, publicKey->W + 1, 64,
|
||||
hashAddress);
|
||||
cx_keccak_init(sha3Context, 256);
|
||||
cx_hash((cx_hash_t *)sha3Context, CX_LAST, publicKey->W + 1, 64,
|
||||
hashAddress);
|
||||
getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context);
|
||||
}
|
||||
|
||||
void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context) {
|
||||
cx_sha3_t *sha3Context) {
|
||||
uint8_t hashChecksum[32];
|
||||
uint8_t tmp[40];
|
||||
uint8_t i;
|
||||
|
@ -191,8 +193,8 @@ void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
|||
tmp[2 * i] = HEXDIGITS[(digit >> 4) & 0x0f];
|
||||
tmp[2 * i + 1] = HEXDIGITS[digit & 0x0f];
|
||||
}
|
||||
app_cx_sha3_init(sha3Context, 256);
|
||||
app_cx_hash((cx_hash_t *)sha3Context, CX_LAST, tmp, 40, hashChecksum);
|
||||
cx_keccak_init(sha3Context, 256);
|
||||
cx_hash((cx_hash_t *)sha3Context, CX_LAST, tmp, 40, hashChecksum);
|
||||
for (i = 0; i < 40; i++) {
|
||||
uint8_t hashDigit = hashChecksum[i / 2];
|
||||
if ((i % 2) == 0) {
|
||||
|
@ -201,7 +203,7 @@ void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
|||
hashDigit = hashDigit & 0x0f;
|
||||
}
|
||||
if ((hashDigit > 7) && (tmp[i] > '9')) {
|
||||
out[i] = tmp[i] /*- 'a' + 'A'*/;
|
||||
out[i] = tmp[i] - 'a' + 'A';
|
||||
} else {
|
||||
out[i] = tmp[i];
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include "app_cx_sha3.h"
|
||||
|
||||
/**
|
||||
* @brief Decode an RLP encoded field - see
|
||||
|
@ -37,13 +36,13 @@ bool rlpDecodeLength(uint8_t *buffer, uint32_t bufferLength,
|
|||
bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid);
|
||||
|
||||
void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context);
|
||||
cx_sha3_t *sha3Context);
|
||||
|
||||
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context);
|
||||
cx_sha3_t *sha3Context);
|
||||
|
||||
void getEthAddressStringFromBinary(uint8_t *address, uint8_t *out,
|
||||
app_cx_sha3_t *sha3Context);
|
||||
cx_sha3_t *sha3Context);
|
||||
|
||||
bool adjustDecimals(char *src, uint32_t srcLength, char *target,
|
||||
uint32_t targetLength, uint8_t decimals);
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include <stdbool.h>
|
||||
#include "app_cx_sha3.h"
|
||||
#include "ethUstream.h"
|
||||
#include "ethUtils.h"
|
||||
#include "uint256.h"
|
||||
|
@ -71,7 +70,7 @@ union {
|
|||
} tmpCtx;
|
||||
txContext_t txContext;
|
||||
txContent_t txContent;
|
||||
app_cx_sha3_t sha3;
|
||||
cx_sha3_t sha3;
|
||||
volatile char addressSummary[21];
|
||||
volatile char address1[21];
|
||||
volatile char address2[21];
|
||||
|
@ -812,17 +811,6 @@ unsigned int ui_address_nanos_button(unsigned int button_mask,
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO : replace with 1.2 SDK
|
||||
int app_cx_ecfp_init_private_key(cx_curve_t curve, unsigned char WIDE *rawkey,
|
||||
int key_len, cx_ecfp_private_key_t *key) {
|
||||
key->curve = curve;
|
||||
key->d_len = key_len;
|
||||
if (rawkey != NULL) {
|
||||
os_memmove(key->d, rawkey, key_len);
|
||||
}
|
||||
return key_len;
|
||||
}
|
||||
|
||||
unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
|
||||
uint8_t privateKeyData[32];
|
||||
uint8_t signature[100];
|
||||
|
@ -830,11 +818,10 @@ unsigned int io_seproxyhal_touch_tx_ok(const bagl_element_t *e) {
|
|||
cx_ecfp_private_key_t privateKey;
|
||||
uint32_t tx = 0;
|
||||
uint8_t rLength, sLength, rOffset, sOffset;
|
||||
os_perso_derive_seed_bip32(tmpCtx.transactionContext.bip32Path,
|
||||
tmpCtx.transactionContext.pathLength,
|
||||
privateKeyData, NULL);
|
||||
app_cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32,
|
||||
&privateKey);
|
||||
os_perso_derive_node_bip32(
|
||||
CX_CURVE_256K1, tmpCtx.transactionContext.bip32Path,
|
||||
tmpCtx.transactionContext.pathLength, privateKeyData, NULL);
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey);
|
||||
os_memset(privateKeyData, 0, sizeof(privateKeyData));
|
||||
signatureLength =
|
||||
cx_ecdsa_sign(&privateKey, CX_RND_RFC6979 | CX_LAST, CX_SHA256,
|
||||
|
@ -997,10 +984,11 @@ void sample_main(void) {
|
|||
(dataBuffer[2] << 8) | (dataBuffer[3]);
|
||||
dataBuffer += 4;
|
||||
}
|
||||
os_perso_derive_seed_bip32(bip32Path, bip32PathLength,
|
||||
privateKeyData, NULL);
|
||||
app_cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData,
|
||||
32, &privateKey);
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path,
|
||||
bip32PathLength, privateKeyData,
|
||||
NULL);
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32,
|
||||
&privateKey);
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1,
|
||||
&tmpCtx.publicKeyContext.publicKey,
|
||||
&privateKey, 1);
|
||||
|
@ -1097,9 +1085,9 @@ void sample_main(void) {
|
|||
}
|
||||
|
||||
// Store the hash
|
||||
app_cx_hash((cx_hash_t *)&sha3, CX_LAST,
|
||||
tmpCtx.transactionContext.hash, 0,
|
||||
tmpCtx.transactionContext.hash);
|
||||
cx_hash((cx_hash_t *)&sha3, CX_LAST,
|
||||
tmpCtx.transactionContext.hash, 0,
|
||||
tmpCtx.transactionContext.hash);
|
||||
// Add address
|
||||
getEthAddressStringFromBinary(txContent.destination,
|
||||
address, &sha3);
|
||||
|
|
|
@ -1,299 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 Ledger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
#include "app_cx_sha3.h"
|
||||
|
||||
#define S64(x, y) state[x + 5 * y]
|
||||
#define ROTL64(x, n) (((x) << (n)) | ((x) >> ((64) - (n))))
|
||||
#define _64BITS(h, l) (h##ULL << 32) | (l##ULL)
|
||||
|
||||
static void cx_sha3_theta(uint64bits_t state[]) {
|
||||
uint64bits_t C[5];
|
||||
uint64bits_t D[5];
|
||||
C[0] = S64(0, 0) ^ S64(0, 1) ^ S64(0, 2) ^ S64(0, 3) ^ S64(0, 4);
|
||||
C[1] = S64(1, 0) ^ S64(1, 1) ^ S64(1, 2) ^ S64(1, 3) ^ S64(1, 4);
|
||||
C[2] = S64(2, 0) ^ S64(2, 1) ^ S64(2, 2) ^ S64(2, 3) ^ S64(2, 4);
|
||||
C[3] = S64(3, 0) ^ S64(3, 1) ^ S64(3, 2) ^ S64(3, 3) ^ S64(3, 4);
|
||||
C[4] = S64(4, 0) ^ S64(4, 1) ^ S64(4, 2) ^ S64(4, 3) ^ S64(4, 4);
|
||||
|
||||
D[0] = C[4] ^ ROTL64(C[1], 1);
|
||||
D[1] = C[0] ^ ROTL64(C[2], 1);
|
||||
D[2] = C[1] ^ ROTL64(C[3], 1);
|
||||
D[3] = C[2] ^ ROTL64(C[4], 1);
|
||||
D[4] = C[3] ^ ROTL64(C[0], 1);
|
||||
|
||||
S64(0, 0) = S64(0, 0) ^ D[0];
|
||||
S64(1, 0) = S64(1, 0) ^ D[1];
|
||||
S64(2, 0) = S64(2, 0) ^ D[2];
|
||||
S64(3, 0) = S64(3, 0) ^ D[3];
|
||||
S64(4, 0) = S64(4, 0) ^ D[4];
|
||||
|
||||
S64(0, 1) = S64(0, 1) ^ D[0];
|
||||
S64(1, 1) = S64(1, 1) ^ D[1];
|
||||
S64(2, 1) = S64(2, 1) ^ D[2];
|
||||
S64(3, 1) = S64(3, 1) ^ D[3];
|
||||
S64(4, 1) = S64(4, 1) ^ D[4];
|
||||
|
||||
S64(0, 2) = S64(0, 2) ^ D[0];
|
||||
S64(1, 2) = S64(1, 2) ^ D[1];
|
||||
S64(2, 2) = S64(2, 2) ^ D[2];
|
||||
S64(3, 2) = S64(3, 2) ^ D[3];
|
||||
S64(4, 2) = S64(4, 2) ^ D[4];
|
||||
|
||||
S64(0, 3) = S64(0, 3) ^ D[0];
|
||||
S64(1, 3) = S64(1, 3) ^ D[1];
|
||||
S64(2, 3) = S64(2, 3) ^ D[2];
|
||||
S64(3, 3) = S64(3, 3) ^ D[3];
|
||||
S64(4, 3) = S64(4, 3) ^ D[4];
|
||||
|
||||
S64(0, 4) = S64(0, 4) ^ D[0];
|
||||
S64(1, 4) = S64(1, 4) ^ D[1];
|
||||
S64(2, 4) = S64(2, 4) ^ D[2];
|
||||
S64(3, 4) = S64(3, 4) ^ D[3];
|
||||
S64(4, 4) = S64(4, 4) ^ D[4];
|
||||
}
|
||||
|
||||
static void cx_sha3_rho(uint64bits_t state[]) {
|
||||
// S64(0,0) = ROTL(S64(1,0), 0);
|
||||
S64(0, 1) = ROTL64(S64(0, 1), 36);
|
||||
S64(0, 2) = ROTL64(S64(0, 2), 3);
|
||||
S64(0, 3) = ROTL64(S64(0, 3), 41);
|
||||
S64(0, 4) = ROTL64(S64(0, 4), 18);
|
||||
|
||||
S64(1, 0) = ROTL64(S64(1, 0), 1);
|
||||
S64(1, 1) = ROTL64(S64(1, 1), 44);
|
||||
S64(1, 2) = ROTL64(S64(1, 2), 10);
|
||||
S64(1, 3) = ROTL64(S64(1, 3), 45);
|
||||
S64(1, 4) = ROTL64(S64(1, 4), 2);
|
||||
|
||||
S64(2, 0) = ROTL64(S64(2, 0), 62);
|
||||
S64(2, 1) = ROTL64(S64(2, 1), 6);
|
||||
S64(2, 2) = ROTL64(S64(2, 2), 43);
|
||||
S64(2, 3) = ROTL64(S64(2, 3), 15);
|
||||
S64(2, 4) = ROTL64(S64(2, 4), 61);
|
||||
|
||||
S64(3, 0) = ROTL64(S64(3, 0), 28);
|
||||
S64(3, 1) = ROTL64(S64(3, 1), 55);
|
||||
S64(3, 2) = ROTL64(S64(3, 2), 25);
|
||||
S64(3, 3) = ROTL64(S64(3, 3), 21);
|
||||
S64(3, 4) = ROTL64(S64(3, 4), 56);
|
||||
|
||||
S64(4, 0) = ROTL64(S64(4, 0), 27);
|
||||
S64(4, 1) = ROTL64(S64(4, 1), 20);
|
||||
S64(4, 2) = ROTL64(S64(4, 2), 39);
|
||||
S64(4, 3) = ROTL64(S64(4, 3), 8);
|
||||
S64(4, 4) = ROTL64(S64(4, 4), 14);
|
||||
}
|
||||
|
||||
static void cx_sha3_pi(uint64bits_t state[]) {
|
||||
uint64bits_t s;
|
||||
|
||||
s = S64(0, 1);
|
||||
S64(0, 1) = S64(3, 0);
|
||||
S64(3, 0) = S64(3, 3);
|
||||
S64(3, 3) = S64(2, 3);
|
||||
S64(2, 3) = S64(1, 2);
|
||||
S64(1, 2) = S64(2, 1);
|
||||
S64(2, 1) = S64(0, 2);
|
||||
S64(0, 2) = S64(1, 0);
|
||||
S64(1, 0) = S64(1, 1);
|
||||
S64(1, 1) = S64(4, 1);
|
||||
S64(4, 1) = S64(2, 4);
|
||||
S64(2, 4) = S64(4, 2);
|
||||
S64(4, 2) = S64(0, 4);
|
||||
S64(0, 4) = S64(2, 0);
|
||||
S64(2, 0) = S64(2, 2);
|
||||
S64(2, 2) = S64(3, 2);
|
||||
S64(3, 2) = S64(4, 3);
|
||||
S64(4, 3) = S64(3, 4);
|
||||
S64(3, 4) = S64(0, 3);
|
||||
S64(0, 3) = S64(4, 0);
|
||||
S64(4, 0) = S64(4, 4);
|
||||
S64(4, 4) = S64(1, 4);
|
||||
S64(1, 4) = S64(3, 1);
|
||||
S64(3, 1) = S64(1, 3);
|
||||
S64(1, 3) = s;
|
||||
}
|
||||
|
||||
static void cx_sha3_chi(uint64bits_t state[]) {
|
||||
uint64bits_t S0y, S1y;
|
||||
|
||||
S0y = S64(0, 0);
|
||||
S1y = S64(1, 0);
|
||||
S64(0, 0) ^= ~S64(1, 0) & S64(2, 0);
|
||||
S64(1, 0) ^= ~S64(2, 0) & S64(3, 0);
|
||||
S64(2, 0) ^= ~S64(3, 0) & S64(4, 0);
|
||||
S64(3, 0) ^= ~S64(4, 0) & S0y;
|
||||
S64(4, 0) ^= ~S0y & S1y;
|
||||
|
||||
S0y = S64(0, 1);
|
||||
S1y = S64(1, 1);
|
||||
S64(0, 1) ^= ~S64(1, 1) & S64(2, 1);
|
||||
S64(1, 1) ^= ~S64(2, 1) & S64(3, 1);
|
||||
S64(2, 1) ^= ~S64(3, 1) & S64(4, 1);
|
||||
S64(3, 1) ^= ~S64(4, 1) & S0y;
|
||||
S64(4, 1) ^= ~S0y & S1y;
|
||||
|
||||
S0y = S64(0, 2);
|
||||
S1y = S64(1, 2);
|
||||
S64(0, 2) ^= ~S64(1, 2) & S64(2, 2);
|
||||
S64(1, 2) ^= ~S64(2, 2) & S64(3, 2);
|
||||
S64(2, 2) ^= ~S64(3, 2) & S64(4, 2);
|
||||
S64(3, 2) ^= ~S64(4, 2) & S0y;
|
||||
S64(4, 2) ^= ~S0y & S1y;
|
||||
|
||||
S0y = S64(0, 3);
|
||||
S1y = S64(1, 3);
|
||||
S64(0, 3) ^= ~S64(1, 3) & S64(2, 3);
|
||||
S64(1, 3) ^= ~S64(2, 3) & S64(3, 3);
|
||||
S64(2, 3) ^= ~S64(3, 3) & S64(4, 3);
|
||||
S64(3, 3) ^= ~S64(4, 3) & S0y;
|
||||
S64(4, 3) ^= ~S0y & S1y;
|
||||
|
||||
S0y = S64(0, 4);
|
||||
S1y = S64(1, 4);
|
||||
S64(0, 4) ^= ~S64(1, 4) & S64(2, 4);
|
||||
S64(1, 4) ^= ~S64(2, 4) & S64(3, 4);
|
||||
S64(2, 4) ^= ~S64(3, 4) & S64(4, 4);
|
||||
S64(3, 4) ^= ~S64(4, 4) & S0y;
|
||||
S64(4, 4) ^= ~S0y & S1y;
|
||||
}
|
||||
|
||||
static const uint64bits_t WIDE C_cx_iota_RC[24] = {
|
||||
_64BITS(0x00000000, 0x00000001), _64BITS(0x00000000, 0x00008082),
|
||||
_64BITS(0x80000000, 0x0000808A), _64BITS(0x80000000, 0x80008000),
|
||||
_64BITS(0x00000000, 0x0000808B), _64BITS(0x00000000, 0x80000001),
|
||||
_64BITS(0x80000000, 0x80008081), _64BITS(0x80000000, 0x00008009),
|
||||
_64BITS(0x00000000, 0x0000008A), _64BITS(0x00000000, 0x00000088),
|
||||
_64BITS(0x00000000, 0x80008009), _64BITS(0x00000000, 0x8000000A),
|
||||
_64BITS(0x00000000, 0x8000808B), _64BITS(0x80000000, 0x0000008B),
|
||||
_64BITS(0x80000000, 0x00008089), _64BITS(0x80000000, 0x00008003),
|
||||
_64BITS(0x80000000, 0x00008002), _64BITS(0x80000000, 0x00000080),
|
||||
_64BITS(0x00000000, 0x0000800A), _64BITS(0x80000000, 0x8000000A),
|
||||
_64BITS(0x80000000, 0x80008081), _64BITS(0x80000000, 0x00008080),
|
||||
_64BITS(0x00000000, 0x80000001), _64BITS(0x80000000, 0x80008008)};
|
||||
|
||||
static void cx_sha3_iota(uint64bits_t state[], int round) {
|
||||
S64(0, 0) ^= C_cx_iota_RC[round];
|
||||
}
|
||||
|
||||
int app_cx_sha3_init(app_cx_sha3_t *hash, int size) {
|
||||
os_memset(hash, 0, sizeof(app_cx_sha3_t));
|
||||
hash->output_size = size >> 3;
|
||||
hash->block_size = (1600 - 2 * size) >> 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void app_cx_sha3_block(app_cx_sha3_t *hash) {
|
||||
uint64bits_t *block;
|
||||
uint64bits_t *acc;
|
||||
int r;
|
||||
|
||||
block = (uint64bits_t *)hash->block;
|
||||
acc = (uint64bits_t *)hash->acc;
|
||||
|
||||
acc[0] ^= block[0];
|
||||
acc[1] ^= block[1];
|
||||
acc[2] ^= block[2];
|
||||
acc[3] ^= block[3];
|
||||
acc[4] ^= block[4];
|
||||
acc[5] ^= block[5];
|
||||
acc[6] ^= block[6];
|
||||
acc[7] ^= block[7];
|
||||
acc[8] ^= block[8];
|
||||
if (hash->block_size > 72) {
|
||||
acc[9] ^= block[9];
|
||||
acc[10] ^= block[10];
|
||||
acc[11] ^= block[11];
|
||||
acc[12] ^= block[12];
|
||||
if (hash->block_size > 104) {
|
||||
acc[13] ^= block[13];
|
||||
acc[14] ^= block[14];
|
||||
acc[15] ^= block[15];
|
||||
acc[16] ^= block[16];
|
||||
if (hash->block_size > 136) {
|
||||
acc[17] ^= block[17];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (r = 0; r < 24; r++) {
|
||||
cx_sha3_theta(acc);
|
||||
cx_sha3_rho(acc);
|
||||
cx_sha3_pi(acc);
|
||||
cx_sha3_chi(acc);
|
||||
cx_sha3_iota(acc, r);
|
||||
}
|
||||
}
|
||||
|
||||
int app_cx_hash(cx_hash_t *hash, int mode, unsigned char WIDE *in, int len,
|
||||
unsigned char *out) {
|
||||
unsigned int r;
|
||||
unsigned char block_size;
|
||||
unsigned char *block;
|
||||
int blen;
|
||||
unsigned char *acc;
|
||||
|
||||
// --- init locals ---
|
||||
block_size = 0;
|
||||
blen = 0;
|
||||
block = NULL;
|
||||
acc = NULL;
|
||||
|
||||
block_size = ((app_cx_sha3_t *)hash)->block_size;
|
||||
block = ((app_cx_sha3_t *)hash)->block;
|
||||
blen = ((app_cx_sha3_t *)hash)->blen;
|
||||
((app_cx_sha3_t *)hash)->blen = 0;
|
||||
acc = (unsigned char *)((app_cx_sha3_t *)hash)->acc;
|
||||
|
||||
// --- append input data and process all blocks ---
|
||||
if ((blen + len) >= block_size) {
|
||||
r = block_size - blen;
|
||||
do {
|
||||
os_memmove(block + blen, in, r);
|
||||
app_cx_sha3_block((app_cx_sha3_t *)hash);
|
||||
blen = 0;
|
||||
hash->counter++;
|
||||
in += r;
|
||||
len -= r;
|
||||
r = block_size;
|
||||
} while (len >= block_size);
|
||||
}
|
||||
|
||||
// --- remainder ---
|
||||
os_memmove(block + blen, in, len);
|
||||
blen += len;
|
||||
((app_cx_sha3_t *)hash)->blen = blen;
|
||||
|
||||
// --- last block ---
|
||||
if (mode & CX_LAST) {
|
||||
os_memset(block + blen, 0, (200 - blen));
|
||||
block[blen] |= 0x01;
|
||||
block[block_size - 1] |= 0x80;
|
||||
app_cx_sha3_block((app_cx_sha3_t *)hash);
|
||||
// provide result
|
||||
len = ((app_cx_sha3_t *)hash)->output_size;
|
||||
if (out) {
|
||||
os_memmove(out, acc, len);
|
||||
}
|
||||
((app_cx_sha3_t *)hash)->blen = 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 Ledger
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
********************************************************************************/
|
||||
|
||||
#include "os.h"
|
||||
#include "cx.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef uint64bits_t
|
||||
typedef unsigned long long uint64bits_t;
|
||||
#endif
|
||||
|
||||
struct app_cx_sha3_s {
|
||||
struct cx_hash_header_s header;
|
||||
|
||||
// x bytes per input block, depends on sha3-xxx output size
|
||||
unsigned int output_size;
|
||||
unsigned char block_size;
|
||||
//
|
||||
int blen;
|
||||
unsigned char block[200];
|
||||
// use 64bits type to ensure alignment
|
||||
uint64bits_t acc[25];
|
||||
// unsigned char acc[200];
|
||||
};
|
||||
typedef struct app_cx_sha3_s app_cx_sha3_t;
|
||||
|
||||
int app_cx_sha3_init(app_cx_sha3_t *hash, int size);
|
||||
void app_cx_sha3_block(app_cx_sha3_t *hash);
|
||||
int app_cx_hash(cx_hash_t *hash, int mode, unsigned char WIDE *in, int len,
|
||||
unsigned char *out);
|
Loading…
Reference in New Issue