You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
3.9 KiB
166 lines
3.9 KiB
// SPDX-FileCopyrightText: 2020 Foundation Devices, Inc. <hello@foundationdevices.com>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
//
|
|
// SPDX-FileCopyrightText: 2018 Coinkite, Inc. <coldcardwallet.com>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
//
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#ifndef PASSPORT_COSIGN_TOOL
|
|
#include "stm32h7xx_hal.h"
|
|
#endif /* PASSPORT_COSIGN_TOOL */
|
|
|
|
#include "utils.h"
|
|
#include "fwheader.h"
|
|
#include "sha256.h"
|
|
#ifndef PASSPORT_COSIGN_TOOL
|
|
#include "secrets.h"
|
|
#endif
|
|
#define UID_LEN (96/8) /* 96 bits (Section 61.1 in STMH753 RM) */
|
|
|
|
void hash_bl(
|
|
uint8_t *bl,
|
|
size_t bllen,
|
|
uint8_t *hash,
|
|
uint8_t hashlen
|
|
)
|
|
{
|
|
SHA256_CTX ctx;
|
|
|
|
sha256_init(&ctx);
|
|
|
|
/* Checksum the bootloader */
|
|
sha256_update(&ctx, bl, bllen);
|
|
sha256_final(&ctx, hash);
|
|
|
|
/* double SHA256 */
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, hash, hashlen);
|
|
sha256_final(&ctx, hash);
|
|
}
|
|
|
|
// This hash is used for the integrity check of the firmware and is not user-facing
|
|
void hash_fw(
|
|
fw_info_t *hdr,
|
|
uint8_t *fw,
|
|
size_t fwlen,
|
|
uint8_t *hash,
|
|
uint8_t hashlen
|
|
)
|
|
{
|
|
SHA256_CTX ctx;
|
|
|
|
sha256_init(&ctx);
|
|
|
|
// Checksum the info block too
|
|
sha256_update(&ctx, (uint8_t *)hdr, sizeof(fw_info_t));
|
|
|
|
/* Checksum the firmware */
|
|
sha256_update(&ctx, fw, fwlen);
|
|
sha256_final(&ctx, hash);
|
|
|
|
/* double SHA256 */
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, hash, hashlen);
|
|
sha256_final(&ctx, hash);
|
|
}
|
|
|
|
|
|
// User-facing hash includes signatures so user can compare to downloaded file.
|
|
// When exclude_hdr is true, only the code part of the firmware is hashed, which
|
|
// would allow a user to build the code themselves and compare the hash with what
|
|
// is in the Passport.
|
|
void hash_fw_user(
|
|
uint8_t *fw,
|
|
size_t fwlen,
|
|
uint8_t *hash,
|
|
uint8_t hashlen,
|
|
bool exclude_hdr
|
|
)
|
|
{
|
|
SHA256_CTX ctx;
|
|
|
|
// Skip the whole header if requested
|
|
if (exclude_hdr) {
|
|
fw += FW_HEADER_SIZE;
|
|
fwlen -= FW_HEADER_SIZE;
|
|
}
|
|
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, fw, fwlen);
|
|
sha256_final(&ctx, hash);
|
|
}
|
|
|
|
#ifndef PASSPORT_COSIGN_TOOL
|
|
void hash_board(
|
|
uint8_t *fw_hash,
|
|
uint8_t fw_hash_len,
|
|
uint8_t *hash,
|
|
uint8_t hashlen
|
|
)
|
|
{
|
|
SHA256_CTX ctx;
|
|
FLASH_TypeDef *flash = (FLASH_TypeDef *)FLASH_R_BASE;
|
|
uint32_t options = (uint32_t)(flash->OPTSR_CUR & FLASH_OPTSR_RDP_Msk);
|
|
|
|
sha256_init(&ctx);
|
|
/* Add in firmware signature */
|
|
sha256_update(&ctx, fw_hash, fw_hash_len);
|
|
/* Add SE serial number */
|
|
sha256_update(&ctx, rom_secrets->se_serial_number, sizeof(rom_secrets->se_serial_number));
|
|
/* Add option bytes */
|
|
sha256_update(&ctx, (uint8_t *)&options, sizeof(uint32_t));
|
|
/* Add unique device ID */
|
|
sha256_update(&ctx, (uint8_t *)UID_BASE, UID_LEN);
|
|
sha256_final(&ctx, hash);
|
|
|
|
/* double SHA256 */
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, hash, hashlen);
|
|
sha256_final(&ctx, hash);
|
|
}
|
|
|
|
void get_device_hash(uint8_t *hash)
|
|
{
|
|
SHA256_CTX ctx;
|
|
sha256_init(&ctx);
|
|
|
|
/* Add SE serial number */
|
|
sha256_update(&ctx, rom_secrets->se_serial_number, sizeof(rom_secrets->se_serial_number));
|
|
|
|
/* One-time pad */
|
|
sha256_update(&ctx, rom_secrets->otp_key, sizeof(rom_secrets->otp_key));
|
|
|
|
/* Pairing secret */
|
|
sha256_update(&ctx, rom_secrets->pairing_secret, sizeof(rom_secrets->pairing_secret));
|
|
|
|
/* Add unique device ID from MCU */
|
|
sha256_update(&ctx, (uint8_t *)UID_BASE, UID_LEN);
|
|
sha256_final(&ctx, hash);
|
|
|
|
/* double SHA256 */
|
|
sha256_init(&ctx);
|
|
sha256_update(&ctx, hash, 32);
|
|
sha256_final(&ctx, hash);
|
|
}
|
|
|
|
bool get_serial_number(
|
|
char *serial_buf,
|
|
uint8_t serial_buf_len
|
|
)
|
|
{
|
|
uint8_t hash[32];
|
|
if (serial_buf_len < 20) {
|
|
return false;
|
|
}
|
|
|
|
get_device_hash(hash);
|
|
|
|
// Format as serial number
|
|
bytes_to_hex_str(hash, 8, serial_buf, 2, '-');
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif /* PASSPORT_COSIGN_TOOL */
|
|
|