Skip to content

Commit

Permalink
Merge pull request #229 from keepkey/pub640
Browse files Browse the repository at this point in the history
Pub640
  • Loading branch information
con5cience authored Feb 21, 2020
2 parents 48de5d5 + 43a9598 commit 61663da
Show file tree
Hide file tree
Showing 60 changed files with 1,916 additions and 177 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "deps/qrenc/QR-Code-generator"]
path = deps/qrenc/QR-Code-generator
url = https://github.com/keepkey/QR-Code-generator.git
[submodule "deps/sca-hardening/SecAESSTM32"]
path = deps/sca-hardening/SecAESSTM32
url = https://github.com/keepkey/SecAESSTM32.git
9 changes: 5 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.7.2)

project(KeepKeyFirmware

VERSION 6.3.0
VERSION 6.4.0

LANGUAGES C CXX ASM)

Expand Down Expand Up @@ -82,10 +82,10 @@ add_definitions(-DBOOTLOADER_MAJOR_VERSION=${BOOTLOADER_MAJOR_VERSION})
add_definitions(-DBOOTLOADER_MINOR_VERSION=${BOOTLOADER_MINOR_VERSION})
add_definitions(-DBOOTLOADER_PATCH_VERSION=${BOOTLOADER_PATCH_VERSION})

add_definitions(-DNDEBUG)

add_definitions(-DBIP39_WORDLIST_PADDED=1)

add_definitions(-DAES_128=1)

if(${KK_DEBUG_LINK})
add_definitions(-DDEBUG_LINK=1)
else()
Expand All @@ -98,6 +98,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Release" OR
"${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel" OR
"${CMAKE_BUILD_TYPE}" STREQUAL "")
add_definitions(-DNDEBUG)
add_definitions(-DMEMORY_PROTECT=1)
if(NOT ${KK_EMULATOR})
message(WARNING
Expand Down Expand Up @@ -136,6 +137,7 @@ add_subdirectory(lib)
add_subdirectory(tools)
add_subdirectory(deps/crypto)
add_subdirectory(deps/qrenc)
add_subdirectory(deps/sca-hardening)

if(${KK_EMULATOR})
add_subdirectory(deps/googletest)
Expand All @@ -155,4 +157,3 @@ if(${KK_EMULATOR})
COMMAND ${CMAKE_BINARY_DIR}/bin/crypto-unit --gtest_output=xml:${CMAKE_BINARY_DIR}/unittests/crypto.xml)

endif()

2 changes: 1 addition & 1 deletion deps/device-protocol
Submodule device-protocol updated 1 files
+3 −3 package.json
2 changes: 1 addition & 1 deletion deps/qrenc/QR-Code-generator
12 changes: 12 additions & 0 deletions deps/sca-hardening/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
set(sources aes128_cbc.c)

if(NOT ${KK_EMULATOR})
set(sources ${sources}
SecAESSTM32/src/aes/affine_aes.S
SecAESSTM32/src/aes/aes.c)
endif()

include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/SecAESSTM32/src/aes)

add_library(SecAESSTM32 ${sources})
1 change: 1 addition & 0 deletions deps/sca-hardening/SecAESSTM32
Submodule SecAESSTM32 added at 71d356
92 changes: 92 additions & 0 deletions deps/sca-hardening/aes128_cbc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include "aes_sca/aes.h"
#include "trezor/crypto/aes/aes.h"
#include "trezor/crypto/memzero.h"

#include <string.h>

AES_RETURN aes128_cbc_sca_encrypt(const unsigned char *key, const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv)
{
#ifdef EMULATOR
# warning "aes128 encryption is not SCA-hardened in this build."
aes_encrypt_ctx ctx;
aes_encrypt_key128(key, &ctx);
aes_cbc_encrypt(ibuf, obuf, len, iv, &ctx);
memzero(&ctx, sizeof(ctx));
return EXIT_SUCCESS;
#else
int nb = len >> AES_BLOCK_SIZE_P2;
STRUCT_AES fctx;
unsigned char out[16];

if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE;

while(nb--)
{
iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1];
iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3];
iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5];
iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7];
iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9];
iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11];
iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13];
iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15];

// if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
if(aes(MODE_KEYINIT|MODE_AESINIT_ENC|MODE_ENC, &fctx, key, iv, out, NULL, NULL) != NO_ERROR)
return EXIT_FAILURE;
memcpy(iv, out, AES_BLOCK_SIZE);

memcpy(obuf, iv, AES_BLOCK_SIZE);
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}

return EXIT_SUCCESS;
#endif
}

AES_RETURN aes128_cbc_sca_decrypt(const unsigned char *key, const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv)
{
#ifdef EMULATOR
# warning "aes128 decryption is not SCA-hardened in this build."
aes_decrypt_ctx ctx;
aes_decrypt_key128(key, &ctx);
aes_cbc_decrypt(ibuf, obuf, len, iv, &ctx);
memzero(&ctx, sizeof(ctx));
return EXIT_SUCCESS;
#else
unsigned char tmp[AES_BLOCK_SIZE];
int nb = len >> AES_BLOCK_SIZE_P2;
STRUCT_AES fctx;


if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE;

while(nb--)
{
memcpy(tmp, ibuf, AES_BLOCK_SIZE);

// if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
if(aes(MODE_KEYINIT|MODE_AESINIT_DEC|MODE_DEC, &fctx, key, ibuf, obuf, NULL, NULL) != NO_ERROR)
return EXIT_FAILURE;

obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1];
obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3];
obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5];
obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7];
obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9];
obuf[10] ^= iv[10]; obuf[11] ^= iv[11];
obuf[12] ^= iv[12]; obuf[13] ^= iv[13];
obuf[14] ^= iv[14]; obuf[15] ^= iv[15];
memcpy(iv, tmp, AES_BLOCK_SIZE);
ibuf += AES_BLOCK_SIZE;
obuf += AES_BLOCK_SIZE;
}

return EXIT_SUCCESS;
#endif
}
1 change: 1 addition & 0 deletions deps/sca-hardening/include/aes_sca/aes.h
20 changes: 20 additions & 0 deletions deps/sca-hardening/include/aes_sca/aes128_cbc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef AES128_CBC_H
#define AES128_CBC_H

#include "trezor/crypto/aes/aes.h"

AES_RETURN aes128_cbc_sca_encrypt(
const unsigned char *key,
const unsigned char *ibuf,
unsigned char *obuf,
int len,
unsigned char *iv);

AES_RETURN aes128_cbc_sca_decrypt(
const unsigned char *key,
const unsigned char *ibuf,
unsigned char *obuf,
int len,
unsigned char *iv);

#endif
1 change: 1 addition & 0 deletions deps/sca-hardening/include/aes_sca/affine_aes.h
1 change: 1 addition & 0 deletions deps/sca-hardening/include/aes_sca/compiler_abstraction.h
6 changes: 4 additions & 2 deletions docs/Storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ it easier to extend for new features later on.
| AdvancedMode policy | bit 12 | | |
| no backup (seedless) | bit 13 | | |
| has_sec_fingerprint | bit 14 | | |
| reserved | bits 15 - 31 | | |
| sca_hardened | bit 15 | | |
| reserved | bits 16 - 31 | | |
| pin_failed_attempts | u32 | 4 | 8 |
| auto_lock_delay_ms | u32 | 4 | 12 |
| language | char[16] | 16 | 16 |
Expand All @@ -108,7 +109,8 @@ it easier to extend for new features later on.
| u2froot | StorageHDNode | 129 | 176 |
| u2f_counter | u32 | 4 | 305 |
| sec_fingerprint | char[32] | 32 | 309 |
| reserved | char[123] | 123 | 341 |
| random_salt | char[32] | 32 | 341 |
| reserved | char[91] | 91 | 373 |
| encrypted_secrets_version | u32 | 4 | 464 |
| encrypted_secrets | char[512] | 512 | 468 |

Expand Down
4 changes: 4 additions & 0 deletions fuzzer/firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(libraries
kkemulator
trezorcrypto
qrcodegenerator
SecAESSTM32
kkrand
kktransport)

Expand All @@ -23,3 +24,6 @@ target_link_libraries(fuzz-eos_formatName ${libraries})

add_executable(fuzz-eos_formatAsset eos_formatAsset.cpp)
target_link_libraries(fuzz-eos_formatAsset ${libraries})

add_executable(fuzz-ripple_decode ripple_decode.cpp)
target_link_libraries(fuzz-ripple_decode ${libraries})
36 changes: 36 additions & 0 deletions fuzzer/firmware/ripple_decode.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
extern "C" {
#include "keepkey/firmware/coins.h"
#include "keepkey/firmware/ripple.h"
#include "keepkey/firmware/ripple_base58.h"
#include "trezor/crypto/hasher.h"
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size != 33)
return 0;

uint8_t buff[64];
memset(buff, 0, sizeof(buff));

Hasher hasher;
hasher_Init(&hasher, HASHER_SHA2_RIPEMD);
hasher_Update(&hasher, data, 33);
hasher_Final(&hasher, buff + 1);

char address[56];
if (!ripple_encode_check(buff, 21, HASHER_SHA2D,
address, MAX_ADDR_SIZE))
return 1;

uint8_t addr_raw[MAX_ADDR_RAW_SIZE];
memset(addr_raw, 0, sizeof(addr_raw));
uint32_t addr_raw_len = ripple_decode_check(address, HASHER_SHA2D,
addr_raw, MAX_ADDR_RAW_SIZE);
if (addr_raw_len != 21)
return 2;

if (memcmp(buff, addr_raw, 21) != 0)
return 3;

return 0;
}
1 change: 1 addition & 0 deletions include/aes_sca
3 changes: 3 additions & 0 deletions include/keepkey/board/keepkey_flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ bool set_mfg_mode_off(void);
const char *flash_getModel(void);
bool flash_setModel(const char (*model)[32]);
const char *flash_programModel(void);

void flash_collectHWEntropy(bool privileged);
void flash_readHWEntropy(uint8_t *buff, size_t size);
#endif
12 changes: 12 additions & 0 deletions include/keepkey/board/memcmp_s.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef KEEPKEY_BOARD_MEMCMPS_H
#define KEEPKEY_BOARD_MEMCMPS_H

#include <stddef.h>

/// Compare two memory regions for equality in constant time.
/// \param lhs must be an array of at least `len` bytes
/// \param rhs must be an array of at least `len` bytes
/// \param len must be in [32, 255), otherwise behavior is undefined.
int memcmp_s(const void *lhs, const void *rhs, size_t len);

#endif
38 changes: 38 additions & 0 deletions include/keepkey/board/otp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (C) 2019 Pavol Rusnak <[email protected]>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __OTP_H__
#define __OTP_H__

#include <stdbool.h>
#include <stdint.h>

#define FLASH_OTP_NUM_BLOCKS 16
#define FLASH_OTP_BLOCK_SIZE 32

#define FLASH_OTP_BLOCK_RANDOMNESS 3

bool flash_otp_is_locked(uint8_t block);
bool flash_otp_lock(uint8_t block);
bool flash_otp_read(uint8_t block, uint8_t offset, uint8_t *data,
uint8_t datalen);
bool flash_otp_write(uint8_t block, uint8_t offset, const uint8_t *data,
uint8_t datalen);

#endif
3 changes: 2 additions & 1 deletion include/keepkey/firmware/coins.def
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ X(true, "GRS Testnet", true, "tGRS", true, 111, true, 100000 , true, 19
X(true, "BCH Testnet", true, "tBCH", true, 0, true, 500000, true, 5, true, "Bitcoin Signed Message:\n", true, 0x80000001, true, 0, true, 8, false, NO_CONTRACT, true, 76067358, true, false, true, true, true, SECP256K1_STRING, true, "bitcoincash", false, "", false, false, false, 0, false, 0, false, "" )
X(true, "LTC Testnet", true, "tLTC", true, 48, true, 1000000, true, 50, true, "Litecoin Signed Message:\n", true, 0x80000001, false, 0, true, 8, false, NO_CONTRACT, true, 27108450, true, true, true, false, true, SECP256K1_STRING, false, "", true, "ltc", false, false, false, 0, false, 0, false, "" )
X(true, ETHEREUM_TST, true, "tETH", true, NA, true, 100000, true, NA, true, "Ethereum Signed Message:\n", true, 0x80000001, true, 1, true, 18, false, NO_CONTRACT, false, 0, true, false, true, false, true, SECP256K1_STRING, false, "", false, "", false, false, false, 0, false, 0, false, "" )
X(true, "Cosmos", true, "ATOM", false, NA, false, NA, false, NA, false, {0}, true, 0x80000076, false, 0, true, 6, false, NO_CONTRACT, false, 0, false, false, false, false, true, SECP256K1_STRING, false, "", true, "cosmos", false, false, false, 0, false, 0, false, "" )
X(true, "Binance", true, "BEP2", false, NA, false, NA, false, NA, false, {0}, true, 0x800002ca, false, 0, true, 8, false, NO_CONTRACT, false, 0, false, false, false, false, true, SECP256K1_STRING, false, "", true, "bnb", false, false, false, 0, false, 0, false, "" )
X(true, "Cosmos", true, "ATOM", false, NA, false, NA, false, NA, false, {0}, true, 0x80000076, false, 0, true, 6, false, NO_CONTRACT, false, 0, false, false, false, false, true, SECP256K1_STRING, false, "", false, "cosmos", false, false, false, 0, false, 0, false, "" )
X(true, "Ripple", true, "Ripple",false, 0, false, 0, false, 0, false, {0}, true, 0x80000090, false, 0, false, 0, false, NO_CONTRACT, false, 0, false, false, false, false, true, SECP256K1_STRING, false, "", false, "", false, false, true, 77429938, true, 78792518, false, "" )
#undef X
#undef NO_CONTRACT
8 changes: 8 additions & 0 deletions include/keepkey/firmware/fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,16 +78,24 @@ void fsm_msgDecryptMessage(DecryptMessage *msg);
//void fsm_msgPassphraseAck(PassphraseAck *msg);
void fsm_msgRecoveryDevice(RecoveryDevice *msg);
void fsm_msgWordAck(WordAck *msg);

void fsm_msgEthereumGetAddress(EthereumGetAddress *msg);
void fsm_msgEthereumSignTx(EthereumSignTx *msg);
void fsm_msgEthereumTxAck(EthereumTxAck *msg);
void fsm_msgEthereumSignMessage(EthereumSignMessage *msg);
void fsm_msgEthereumVerifyMessage(const EthereumVerifyMessage *msg);

void fsm_msgCharacterAck(CharacterAck *msg);
void fsm_msgApplyPolicies(ApplyPolicies *msg);

void fsm_msgNanoGetAddress(NanoGetAddress *msg);
void fsm_msgNanoSignTx(NanoSignTx *msg);

/// Modifies the RippleSignTx, setting the flag to indicate
/// that the ECDSA sig is canonical.
void fsm_msgRippleSignTx(RippleSignTx *msg);
void fsm_msgRippleGetAddress(const RippleGetAddress *msg);

void fsm_msgEosGetPublicKey(const EosGetPublicKey *msg);
void fsm_msgEosSignTx(const EosSignTx *msg);
void fsm_msgEosTxActionAck(const EosTxActionAck *msg);
Expand Down
Loading

0 comments on commit 61663da

Please sign in to comment.