From d071ae9e92bcf243a34b988e84ec319feb96011f Mon Sep 17 00:00:00 2001 From: keiff3r Date: Mon, 9 Dec 2024 15:59:05 +0100 Subject: [PATCH] feat(exportPrivateKey): support new key derivation paths - Added support for new key derivation paths by introducing `isNewPath` flag in `exportPrivateKeyContext_t`. - Updated `exportPrivateKeySeed` and `exportPrivateKeyBls` functions to handle both legacy and new paths. - Modified `handleExportPrivateKey` to parse `dataBuffer` for new path information and adjust key derivation path accordingly. - Extended `display` buffer size in `exportPrivateKeyContext_t` to accommodate new path display information. - Updated `derivation_path_keys_t` enum to include new path keys `NEW_ID_CRED_SEC` and `NEW_PRF_KEY`. --- src/exportPrivateKey.c | 103 ++++++++++++++++++++++++++++++++--------- src/exportPrivateKey.h | 3 +- src/globals.h | 8 +++- 3 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/exportPrivateKey.c b/src/exportPrivateKey.c index 9a11c34f..29c4f144 100644 --- a/src/exportPrivateKey.c +++ b/src/exportPrivateKey.c @@ -16,25 +16,34 @@ static const uint32_t HARDENED_OFFSET = 0x80000000; static exportPrivateKeyContext_t *ctx = &global.exportPrivateKeyContext; -#define ID_CRED_SEC 0 -#define PRF_KEY 1 - -#define pathLength 6 - void exportPrivateKeySeed(void) { cx_ecfp_private_key_t privateKey; BEGIN_TRY { TRY { - ctx->path[5] = PRF_KEY | HARDENED_OFFSET; - getPrivateKey(ctx->path, pathLength, &privateKey); + uint8_t lastSubPath; + uint8_t lastSubPathIndex; + if (ctx->isNewPath) { + lastSubPath = NEW_PRF_KEY; + lastSubPathIndex = 4; + } else { + lastSubPath = LEGACY_PRF_KEY; + lastSubPathIndex = 5; + } + ctx->path[lastSubPathIndex] = lastSubPath | HARDENED_OFFSET; + getPrivateKey(ctx->path, lastSubPathIndex + 1, &privateKey); uint8_t tx = 0; for (int i = 0; i < 32; i++) { G_io_apdu_buffer[tx++] = privateKey.d[i]; } if (ctx->exportBoth) { - ctx->path[5] = ID_CRED_SEC | HARDENED_OFFSET; - getPrivateKey(ctx->path, pathLength, &privateKey); + if (ctx->isNewPath) { + lastSubPath = NEW_ID_CRED_SEC; + } else { + lastSubPath = LEGACY_ID_CRED_SEC; + } + ctx->path[lastSubPathIndex] = lastSubPath | HARDENED_OFFSET; + getPrivateKey(ctx->path, lastSubPathIndex + 1, &privateKey); for (int i = 0; i < 32; i++) { G_io_apdu_buffer[tx++] = privateKey.d[i]; } @@ -53,15 +62,29 @@ void exportPrivateKeyBls(void) { uint8_t privateKey[32]; BEGIN_TRY { TRY { - ctx->path[5] = PRF_KEY | HARDENED_OFFSET; - getBlsPrivateKey(ctx->path, pathLength, privateKey, sizeof(privateKey)); + uint8_t lastSubPath; + uint8_t lastSubPathIndex; + if (ctx->isNewPath) { + lastSubPath = NEW_PRF_KEY; + lastSubPathIndex = 4; + } else { + lastSubPath = LEGACY_PRF_KEY; + lastSubPathIndex = 5; + } + ctx->path[lastSubPathIndex] = lastSubPath | HARDENED_OFFSET; + getBlsPrivateKey(ctx->path, lastSubPathIndex + 1, privateKey, sizeof(privateKey)); uint8_t tx = 0; memmove(G_io_apdu_buffer, privateKey, sizeof(privateKey)); tx += sizeof(privateKey); if (ctx->exportBoth) { - ctx->path[5] = ID_CRED_SEC | HARDENED_OFFSET; - getBlsPrivateKey(ctx->path, pathLength, privateKey, sizeof(privateKey)); + if (ctx->isNewPath) { + lastSubPath = NEW_ID_CRED_SEC; + } else { + lastSubPath = LEGACY_ID_CRED_SEC; + } + ctx->path[lastSubPathIndex] = lastSubPath | HARDENED_OFFSET; + getBlsPrivateKey(ctx->path, lastSubPathIndex + 1, privateKey, sizeof(privateKey)); memmove(G_io_apdu_buffer + tx, privateKey, sizeof(privateKey)); tx += sizeof(privateKey); } @@ -105,19 +128,55 @@ void handleExportPrivateKey(uint8_t *dataBuffer, (p2 != P2_KEY && p2 != P2_SEED)) { THROW(ERROR_INVALID_PARAM); } - uint32_t identity = U4BE(dataBuffer, 0); - uint32_t keyDerivationPath[5] = {LEGACY_PURPOSE | HARDENED_OFFSET, - LEGACY_COIN_TYPE | HARDENED_OFFSET, - ACCOUNT_SUBTREE | HARDENED_OFFSET, - NORMAL_ACCOUNTS | HARDENED_OFFSET, - identity | HARDENED_OFFSET}; - memmove(ctx->path, keyDerivationPath, sizeof(keyDerivationPath)); + size_t offset = 0; + PRINTF("km------------------------dataBuffer: %s\n", dataBuffer[offset]); + + ctx->isNewPath = (bool) dataBuffer[offset]; + PRINTF("km------------------------dataBuffer: %s\n", dataBuffer[offset]); + offset += 1; + + uint32_t identity_provider; + uint32_t identity; + if (ctx->isNewPath) { + identity_provider = U4BE(dataBuffer, offset); + offset += 4; + } + identity = U4BE(dataBuffer, offset); + offset += 4; + uint32_t *keyDerivationPath; + size_t pathLength; + if (ctx->isNewPath) { + keyDerivationPath = (uint32_t[4]){NEW_PURPOSE | HARDENED_OFFSET, + NEW_COIN_TYPE | HARDENED_OFFSET, + identity_provider | HARDENED_OFFSET, + identity | HARDENED_OFFSET}; + pathLength = 4; + } else { + keyDerivationPath = (uint32_t[5]){LEGACY_PURPOSE | HARDENED_OFFSET, + LEGACY_COIN_TYPE | HARDENED_OFFSET, + ACCOUNT_SUBTREE | HARDENED_OFFSET, + NORMAL_ACCOUNTS | HARDENED_OFFSET, + identity | HARDENED_OFFSET}; + pathLength = 5; + } + memmove(ctx->path, keyDerivationPath, pathLength * sizeof(uint32_t)); + ctx->pathLength = pathLength * sizeof(uint32_t); ctx->exportBoth = p1 == P1_BOTH; ctx->exportSeed = p2 == P2_SEED; - memmove(ctx->display, "ID #", 4); - bin2dec(ctx->display + 4, sizeof(ctx->display) - 4, identity); + // Reset the offset to 0 + offset = 0; + if (ctx->isNewPath) { + memmove(ctx->display, "IDP#", 4); + offset += 4; + bin2dec(ctx->display + offset, sizeof(ctx->display) - offset, identity_provider); + offset += 4; + } + + memmove(ctx->display + offset, "ID #", 4); + offset += 4; + bin2dec(ctx->display + offset, sizeof(ctx->display) - offset, identity); if (p1 == P1_BOTH) { memmove(ctx->displayHeader, "Create credential", 18); diff --git a/src/exportPrivateKey.h b/src/exportPrivateKey.h index 8cdab476..e038ca48 100644 --- a/src/exportPrivateKey.h +++ b/src/exportPrivateKey.h @@ -15,11 +15,12 @@ void handleExportPrivateKey(uint8_t *dataBuffer, typedef struct { uint8_t displayHeader[20]; - uint8_t display[15]; + uint8_t display[22]; bool exportBoth; bool exportSeed; uint32_t path[6]; uint8_t pathLength; + bool isNewPath; } exportPrivateKeyContext_t; void uiExportPrivateKey(volatile unsigned int *flags); diff --git a/src/globals.h b/src/globals.h index 3509f464..30137489 100644 --- a/src/globals.h +++ b/src/globals.h @@ -33,7 +33,13 @@ #define ACCOUNT_TRANSACTION_HEADER_LENGTH 60 #define UPDATE_HEADER_LENGTH 28 -typedef enum { LEGACY_PRF_KEY = 1, NEW_PRF_KEY = 3 } derivation_path_keys_t; +typedef enum { + LEGACY_ID_CRED_SEC = 0, + LEGACY_PRF_KEY = 1, + // New path + NEW_ID_CRED_SEC = 2, + NEW_PRF_KEY = 3 +} derivation_path_keys_t; typedef enum { DEPLOY_MODULE = 0,