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:
BTChip 2016-08-12 15:53:40 +02:00
parent 4a1dfa0c8b
commit 0eb82c6f98
8 changed files with 56 additions and 411 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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];
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);