From 3f7e75c49a632ed0b483a9a2ef3140de6faa1224 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 14:42:27 +0000 Subject: [PATCH 1/7] add flare CLA extra verification --- app/src/apdu_handler.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index 131625b..bdbb34a 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -242,23 +242,35 @@ void handleApdu(volatile uint32_t *flags, volatile uint32_t *tx, uint32_t rx) { } else { switch (instruction) { case INS_GET_VERSION: { + if (cla != CLA) { + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } handle_getversion(flags, tx); break; } case INS_GET_ADDR: { + if (cla != CLA) { + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } CHECK_PIN_VALIDATED() handleGetAddr(flags, tx, rx); break; } case INS_SIGN: { + if (cla != CLA) { + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } CHECK_PIN_VALIDATED() handleSign(flags, tx, rx); break; } case INS_SIGN_HASH: { + if (cla != CLA) { + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } CHECK_PIN_VALIDATED() handleSignHash(flags, tx, rx); break; From 64c28b008ff4015cafb5db82a6cb10291584e192 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 14:52:25 +0000 Subject: [PATCH 2/7] remove not needed DER signature from response --- app/src/evm/crypto_eth.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/evm/crypto_eth.c b/app/src/evm/crypto_eth.c index 5fb2a2e..bb0077b 100644 --- a/app/src/evm/crypto_eth.c +++ b/app/src/evm/crypto_eth.c @@ -118,8 +118,7 @@ zxerr_t _sign(uint8_t *output, uint16_t outputLen, const uint8_t *message, uint1 const err_convert_e err_c = convertDERtoRSV(signature->der_signature, tmpInfo, signature->r, signature->s, &signature->v); if (err_c == no_error) { - *sigSize = - sizeof_field(signature_t, r) + sizeof_field(signature_t, s) + sizeof_field(signature_t, v) + signatureLength; + *sigSize = sizeof_field(signature_t, r) + sizeof_field(signature_t, s) + sizeof_field(signature_t, v); if (info != NULL) { *info = tmpInfo; } From 74ee9dad10440b93b6a21f02c8741f5d0cbf816c Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 14:57:27 +0000 Subject: [PATCH 3/7] update zxlib --- deps/ledger-zxlib | 2 +- tests_zemu/package.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/deps/ledger-zxlib b/deps/ledger-zxlib index bca1c75..fec0d14 160000 --- a/deps/ledger-zxlib +++ b/deps/ledger-zxlib @@ -1 +1 @@ -Subproject commit bca1c75a00f2a6f7dd55ef64da1abeb0f1701c61 +Subproject commit fec0d14a886c9ce711867022d1eae52e95cdc19b diff --git a/tests_zemu/package.json b/tests_zemu/package.json index 991efc2..a125b42 100644 --- a/tests_zemu/package.json +++ b/tests_zemu/package.json @@ -28,15 +28,15 @@ "@types/jest": "^29.5.12", "@types/ledgerhq__hw-transport": "^4.21.4", "@types/secp256k1": "^4.0.6", - "@typescript-eslint/eslint-plugin": "^8.17.0", - "@typescript-eslint/parser": "^8.17.0", + "@typescript-eslint/eslint-plugin": "^8.18.1", + "@typescript-eslint/parser": "^8.18.1", "blakejs": "^1.1.1", "crypto-js": "4.2.0", "ed25519-supercop": "^2.0.1", - "eslint": "^9.16.0", + "eslint": "^9.17.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.24.2", - "eslint-plugin-jest": "^28.9.0", + "eslint-plugin-jest": "^28.10.0", "eslint-plugin-prettier": "^5.1.3", "jest": "29.7.0", "js-sha256": "0.11.0", From 6eb9732446f91f26daf03cdde251542609ea8210 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 17:36:40 +0000 Subject: [PATCH 4/7] bump version --- app/Makefile.version | 2 +- tests_zemu/snapshots/fl-mainmenu/00004.png | Bin 9479 -> 9676 bytes tests_zemu/snapshots/s-mainmenu/00005.png | Bin 398 -> 391 bytes tests_zemu/snapshots/s-mainmenu/00009.png | Bin 398 -> 391 bytes tests_zemu/snapshots/sp-mainmenu/00005.png | Bin 343 -> 348 bytes tests_zemu/snapshots/sp-mainmenu/00009.png | Bin 343 -> 348 bytes tests_zemu/snapshots/st-mainmenu/00004.png | Bin 11245 -> 11432 bytes tests_zemu/snapshots/x-mainmenu/00005.png | Bin 343 -> 348 bytes tests_zemu/snapshots/x-mainmenu/00009.png | Bin 343 -> 348 bytes 9 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Makefile.version b/app/Makefile.version index 2c65550..63f278b 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -3,4 +3,4 @@ APPVERSION_M=2 # This is the minor version APPVERSION_N=4 # This is the patch version -APPVERSION_P=2 +APPVERSION_P=3 diff --git a/tests_zemu/snapshots/fl-mainmenu/00004.png b/tests_zemu/snapshots/fl-mainmenu/00004.png index 5401a43f77fbe1d7d917511d5cdd8d980b3039e4..16476e1c80a12966f50c20ca3a7e47b2e28ff596 100644 GIT binary patch literal 9676 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 diff --git a/tests_zemu/snapshots/s-mainmenu/00005.png b/tests_zemu/snapshots/s-mainmenu/00005.png index b1453e27bf9b0f9e8131ff96e47d3859937e5333..97772c4a25684b879e757eeddc75d09091531877 100644 GIT binary patch delta 364 zcmV-y0h9iY1BU~UB!5mxL_t(|ob8#*5`!QNMX^)=|ASrF1x_Y}$0SNK0{2W87E#L0 zgFr(7006Kmo6|Vwkq*0GE!*z&1K!Hlb+qN>&ha%s4IUq4r1Ox0QtUQ3AJ@^&L*}B$ zwqKu+s+?aJyN%2{Qcy!pA@?l06FLJ}r)|m)wIuWW%_HEOf`4u^o$ka73_!l$c7NV& zqC}+I2Pn%A>Nc;#cBfwiOyrfGlosJwfY*S~R&qUAOBMlq`vbZl^i1uMt^xd>xaO}D zW4d3ka933n!>4eZaT%$ki81(I91IaxP3}7{?U-p z0CBcf8;GqFePt#27RG3RDBQh_#Gh5_-Y$qkYRfUPr=ae^{zSp$Qc!mq!ii`bR^m2Z z2H<|0J3DU?D+Jx*o05r)q5D7JPZ?Ht_l>ok7j1|Z+hyFYI> zQ6kc<1C-?lHJjIAt5YumCi2Rbq$XisfL{Tjt;Bk=J5dDintr?SZr*o6*H{YbBqz-wJXa={8^=T`GR-~>?x>vu-`ly8~kML>Aj$zDL%gu zJ#6YHS{Z<6q1apb9olQ-r!+2{LgEwVVbM*(e;T3iZfh?$9|r&c0002b@dY;coBInq Rs;>Y5002ovPDHLkV1nfcrP2TZ diff --git a/tests_zemu/snapshots/s-mainmenu/00009.png b/tests_zemu/snapshots/s-mainmenu/00009.png index b1453e27bf9b0f9e8131ff96e47d3859937e5333..97772c4a25684b879e757eeddc75d09091531877 100644 GIT binary patch delta 364 zcmV-y0h9iY1BU~UB!5mxL_t(|ob8#*5`!QNMX^)=|ASrF1x_Y}$0SNK0{2W87E#L0 zgFr(7006Kmo6|Vwkq*0GE!*z&1K!Hlb+qN>&ha%s4IUq4r1Ox0QtUQ3AJ@^&L*}B$ zwqKu+s+?aJyN%2{Qcy!pA@?l06FLJ}r)|m)wIuWW%_HEOf`4u^o$ka73_!l$c7NV& zqC}+I2Pn%A>Nc;#cBfwiOyrfGlosJwfY*S~R&qUAOBMlq`vbZl^i1uMt^xd>xaO}D zW4d3ka933n!>4eZaT%$ki81(I91IaxP3}7{?U-p z0CBcf8;GqFePt#27RG3RDBQh_#Gh5_-Y$qkYRfUPr=ae^{zSp$Qc!mq!ii`bR^m2Z z2H<|0J3DU?D+Jx*o05r)q5D7JPZ?Ht_l>ok7j1|Z+hyFYI> zQ6kc<1C-?lHJjIAt5YumCi2Rbq$XisfL{Tjt;Bk=J5dDintr?SZr*o6*H{YbBqz-wJXa={8^=T`GR-~>?x>vu-`ly8~kML>Aj$zDL%gu zJ#6YHS{Z<6q1apb9olQ-r!+2{LgEwVVbM*(e;T3iZfh?$9|r&c0002b@dY;coBInq Rs;>Y5002ovPDHLkV1nfcrP2TZ diff --git a/tests_zemu/snapshots/sp-mainmenu/00005.png b/tests_zemu/snapshots/sp-mainmenu/00005.png index fc23331b6bfcb4bac618c324a072b9cd432e367a..780acf6078b6a7a0c94d7ff060ca782b32f081e6 100644 GIT binary patch delta 321 zcmcc4bcbnzO1-kDi(^Q|oVPcl`3@-vv_8zb!}&Y@(wn2~k61LPw=J0){CB^)zNzGS zhM+rU3)4#&cMzXJr7ntX;XNDDKKYLeyMf$>(=#*I|;d0COvFHk)zk8Ke zVE%@g{eKI$K224+pB>cZF?Ii1X``3%%LGkd#`nm%B#Cw%d0()kcF(Tm3su)w@7aAm z-7$OqQN?CXtGjQq{qlBNKh#>*ywdczofz-Ai?jaDn78}o9nSYB&o(qZO`PYy#I(9# zHrtm==QsY6xb9>1vu>5^;~)A5KkW|8`&{p^b@m)R_d3Sg0SK=${JSiz_Gy3bbA}an OL86|nelF{r5}E*nvX*WD delta 316 zcmcb^be(B}O1+$?i(^Q|oVPau`3@-vxL(YvS|;$b$oTT)GY7P?e%w$ zZ(gwTe3D19!*2U;rtQ)1<`)QFPRP2twcoS1cuST&+xfdQ8W#8I6yFrw>C3!_mdK II;Vst0KSHkLjV8( diff --git a/tests_zemu/snapshots/sp-mainmenu/00009.png b/tests_zemu/snapshots/sp-mainmenu/00009.png index fc23331b6bfcb4bac618c324a072b9cd432e367a..780acf6078b6a7a0c94d7ff060ca782b32f081e6 100644 GIT binary patch delta 321 zcmcc4bcbnzO1-kDi(^Q|oVPcl`3@-vv_8zb!}&Y@(wn2~k61LPw=J0){CB^)zNzGS zhM+rU3)4#&cMzXJr7ntX;XNDDKKYLeyMf$>(=#*I|;d0COvFHk)zk8Ke zVE%@g{eKI$K224+pB>cZF?Ii1X``3%%LGkd#`nm%B#Cw%d0()kcF(Tm3su)w@7aAm z-7$OqQN?CXtGjQq{qlBNKh#>*ywdczofz-Ai?jaDn78}o9nSYB&o(qZO`PYy#I(9# zHrtm==QsY6xb9>1vu>5^;~)A5KkW|8`&{p^b@m)R_d3Sg0SK=${JSiz_Gy3bbA}an OL86|nelF{r5}E*nvX*WD delta 316 zcmcb^be(B}O1+$?i(^Q|oVPau`3@-vxL(YvS|;$b$oTT)GY7P?e%w$ zZ(gwTe3D19!*2U;rtQ)1<`)QFPRP2twcoS1cuST&+xfdQ8W#8I6yFrw>C3!_mdK II;Vst0KSHkLjV8( diff --git a/tests_zemu/snapshots/st-mainmenu/00004.png b/tests_zemu/snapshots/st-mainmenu/00004.png index 49af25a0f9d687e17231878da4343ee4f2a2c60c..91b4717efc9eadebbbb777caa736ca7b67400695 100644 GIT binary patch literal 11432 zcmeI2cTiJ%*Y6`DsMN#ZNRg(}lmH%zbPy3SLQvGuA)tUp3`hx`graan1r5D>s7mih zLPx<6ngoat0Wm;;NG|~r;NAG#JM+vt_uhBzoq3*l|G4>wnLT^++xxfo`mWFVuJ!zu zxe3on(UTw$hzD~0>TM9{$ZHUY?d@?k;E49k#$pf%>Ms6(+)d3Z!}*407YQ2K7k&YfdOX zQPR9zToeQu2K@{&blMDU8GSr4IZ3PvK`#PF{G1@RwMcpfWzp|unRplilWmilZE46q zgxc#FgXb?ZZ!)onG;P{gUE&*W;V3ULgIuo{ndWjDl#8Qndpb#yvpNTl(8)RS`dK-2 z+(qvEL8;?P$wZ%p(1!IL-2;W=9k;f6*6kf3*y&oN#0uY3i2lu`T%B)L#$*)Afs7hQ zjSJcC%1>@tty6Rn*EN^y5CLsToIKNUT~xQ~(Z`p%sH?xtP#*+zzJ6UJ;4F+DqwMaF z)r~JRqC2LBdD=WTR$9-NhQM{VnwMwHqMU`<+opN@w8n?jUim1+YuSxyFzcbM+t6x`++7MvxLzUt?8Kue9G$sS|xBD&l!?qVjs*wRn-DZ+xg!8Jm=xX z%skKjs-GeH^k=kX63PK99qFyV$Nf?#ihBPGG?HvkYLTudRc*UFwMraf%avb)lkZF? zPol=9>^d&?tcQd|J?NXLg}*{Krc#1pIXO-tWSS+cRT<+fu6_)D^7()`uvN9*Rbab- zf_|8TtJNvH2_k>>O6po1P-2tIR`Uo?=2i}&a2eBkNSGHF`O z!me`1%{l9BoVx8mF4oxoTfa&5U1VnZDdxk@`4eC2Z|-N8>qU5ZTCFdUj0Vhe{8nq; z2Wc{fQ(RLURfIGA9OTN~;kRRWA}*i&5;?50`Sju3%LgT$nICtmX$OxssNzvmo)X%P zAMaSM3oqils=(Gsd6my5&VhNJW+7=B zOu3+b<02uP5h}?ZzL7Vm#?$eno`SGgi{wZZR5ExO{1$@!9HBgJ(pz5$Hq|TB?Z>Pu zE++?EcgjZ;HF?qOvC;|?r|X!%o#!OKif(vP@vv||U}E#&@^YJKBf(S?|^ zHX;07l^jh5*EgcQcTZ#>CNwLO?DYTYw3QIBu9~<}SXor0Eyn8?Ia}+8&&-4IvkUCq zs~-I(#BOY1PbZCU=)_Ppi7NAjJ<6Dad#}92Ochm-h05Br2r1zZ*qfH8XSt1b*z1tN zi!D7m`bmRSpFVY{kFJDVaBskC6P^=$Jy@-6c(cof$5{RDj}t>gFn33-c4KtM-$g|Q z2wCQN_u+S$vOKbi&?Q=ks5O--5M=48mv13Bj0)Axl+I-^Lj{d>dH2-#LXrmHWc?4G zf6dg~oPyhW`>Ygr`=%jS6%&9Mc+@lZ_G4#zxxKAQEbd)zVYFwj`2%;N+Hk?4!+ijh z8XBMN*(+XY80X{5(rskXslS+hB?2j)^a-CLo|4?_~o?Db=Oit=DYG;F=Rn{A- zzOZ%-g`|J~Q@mwi6`Rbo#KrMF@h)z0a&7cxi(7eFp8R)q?Ja)bop3L87b4PV4U#S@ zue>K8ug-XjY~0B3u}LDZ_2KQ%iYZBCc}W3-P!=DApB=aU_H_QihS4|A%MRrDegX7e zy6SXYB&(6KxP8~4EjvfPGrQ2_yZh

tvBq?}=%*&$juc*13J7dIuEIl|4P>3bE8< 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 literal 11245 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 OL86|nelF{r5}E*nvX*WD delta 316 zcmcb^be(B}O1+$?i(^Q|oVPau`3@-vxL(YvS|;$b$oTT)GY7P?e%w$ zZ(gwTe3D19!*2U;rtQ)1<`)QFPRP2twcoS1cuST&+xfdQ8W#8I6yFrw>C3!_mdK II;Vst0KSHkLjV8( diff --git a/tests_zemu/snapshots/x-mainmenu/00009.png b/tests_zemu/snapshots/x-mainmenu/00009.png index fc23331b6bfcb4bac618c324a072b9cd432e367a..780acf6078b6a7a0c94d7ff060ca782b32f081e6 100644 GIT binary patch delta 321 zcmcc4bcbnzO1-kDi(^Q|oVPcl`3@-vv_8zb!}&Y@(wn2~k61LPw=J0){CB^)zNzGS zhM+rU3)4#&cMzXJr7ntX;XNDDKKYLeyMf$>(=#*I|;d0COvFHk)zk8Ke zVE%@g{eKI$K224+pB>cZF?Ii1X``3%%LGkd#`nm%B#Cw%d0()kcF(Tm3su)w@7aAm z-7$OqQN?CXtGjQq{qlBNKh#>*ywdczofz-Ai?jaDn78}o9nSYB&o(qZO`PYy#I(9# zHrtm==QsY6xb9>1vu>5^;~)A5KkW|8`&{p^b@m)R_d3Sg0SK=${JSiz_Gy3bbA}an OL86|nelF{r5}E*nvX*WD delta 316 zcmcb^be(B}O1+$?i(^Q|oVPau`3@-vxL(YvS|;$b$oTT)GY7P?e%w$ zZ(gwTe3D19!*2U;rtQ)1<`)QFPRP2twcoS1cuST&+xfdQ8W#8I6yFrw>C3!_mdK II;Vst0KSHkLjV8( From b12c144304c55c5c629bedb9a64a9ebed3b53375 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 18:12:26 +0000 Subject: [PATCH 5/7] update fuzzer --- fuzz/parser_parse.cpp | 4 +++- fuzz/run-fuzz-crashes.py | 2 +- tests/expected_output.cpp | 8 +++++--- tests/parser_impl.cpp | 12 +++++++----- tests/ui_tests.cpp | 13 ++++++++++++- tests/utils/common.cpp | 3 +++ 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/fuzz/parser_parse.cpp b/fuzz/parser_parse.cpp index 4d6b303..d8fb66a 100644 --- a/fuzz/parser_parse.cpp +++ b/fuzz/parser_parse.cpp @@ -3,7 +3,9 @@ #include #include "parser.h" -#include "zxformat.h" +#include "parser_common.h" +#include "parser_txdef.h" +#include "zxmacros_x64.h" #ifdef NDEBUG #error "This fuzz target won't work correctly with NDEBUG defined, which will cause asserts to be eliminated" diff --git a/fuzz/run-fuzz-crashes.py b/fuzz/run-fuzz-crashes.py index d6d32be..31eb429 100755 --- a/fuzz/run-fuzz-crashes.py +++ b/fuzz/run-fuzz-crashes.py @@ -20,7 +20,7 @@ artifact_dir = os.path.join('fuzz', 'corpora', f'{fuzzer}-artifacts') corpus_dir = os.path.join('fuzz', 'corpora', f'{fuzzer}') - fuzz_path = os.path.join(f'build/bin/fuzz-{fuzzer}') + fuzz_path = os.path.join(f'build/fuzz-{fuzzer}') os.makedirs(artifact_dir, exist_ok=True) os.makedirs(corpus_dir, exist_ok=True) diff --git a/tests/expected_output.cpp b/tests/expected_output.cpp index 99ab86e..5d83154 100644 --- a/tests/expected_output.cpp +++ b/tests/expected_output.cpp @@ -17,11 +17,13 @@ #include #include -#include +#include +#include +#include -#include "testcases.h" +#include "json/value.h" #include "zxformat.h" -#include "zxmacros.h" +#include "zxmacros_x64.h" const uint32_t fieldSize = 39; template diff --git a/tests/parser_impl.cpp b/tests/parser_impl.cpp index 7c01695..672c3e8 100644 --- a/tests/parser_impl.cpp +++ b/tests/parser_impl.cpp @@ -14,20 +14,22 @@ * limitations under the License. ********************************************************************************/ -#include "parser_impl.h" - #include +#include -#include -#include +#include +#include #include "bech32.h" #include "coin.h" #include "crypto_helper.h" -#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "hexutils.h" #include "parser.h" +#include "parser_common.h" #include "parser_txdef.h" +#include "segwit_addr.h" +#include "zxerror.h" extern "C" { #include "ripemd160.h" diff --git a/tests/ui_tests.cpp b/tests/ui_tests.cpp index 264378e..ba404cb 100644 --- a/tests/ui_tests.cpp +++ b/tests/ui_tests.cpp @@ -15,16 +15,27 @@ ********************************************************************************/ #include -#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include +#include +#include #include "app_mode.h" #include "expected_output.h" #include "gmock/gmock.h" +#include "gtest/gtest.h" #include "parser.h" +#include "parser_common.h" #include "parser_eth.h" #include "testcases.h" #include "utils/common.h" diff --git a/tests/utils/common.cpp b/tests/utils/common.cpp index bf7e2b0..8062671 100644 --- a/tests/utils/common.cpp +++ b/tests/utils/common.cpp @@ -17,9 +17,12 @@ #include +#include #include #include +#include +#include "parser_common.h" #include "parser_eth.h" std::vector dumpUI(parser_context_t *ctx, uint16_t maxKeyLen, uint16_t maxValueLen, bool is_eth) { From e0cea6ded610938b4a479bd1591113767ae65f5d Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 18:28:17 +0000 Subject: [PATCH 6/7] update docs --- docs/APDUSPEC.md | 53 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/docs/APDUSPEC.md b/docs/APDUSPEC.md index eb3aff8..17c0dce 100644 --- a/docs/APDUSPEC.md +++ b/docs/APDUSPEC.md @@ -44,7 +44,7 @@ The general structure of commands and responses is as follows: ## Command definition -### GET_DEVICE_INFO +### INS_GET_DEVICE_INFO #### Command @@ -70,7 +70,7 @@ The general structure of commands and responses is as follows: --- -### GET_VERSION +### INS_GET_VERSION #### Command @@ -211,6 +211,10 @@ All other packets/chunks contain data chunks that are described below --- +## ETH INSTRUCTIONS + +For eth instructions the derivation path length can vary between 3 and 5 elements. + ### INS_GET_ADDR_ETH #### Command @@ -220,7 +224,7 @@ All other packets/chunks contain data chunks that are described below | CLA | byte (1) | Application Identifier | 0xE0 | | INS | byte (1) | Instruction ID | 0x02 | | P1 | byte (1) | Request User confirmation | No = 0 | -| P2 | byte (1) | Chain code | no chain code - 0x0 / chain code - 0x01 | +| P2 | byte (1) | Chain code | no chain code - 0x0 / chain code - 0x01 | | L | byte (1) | Bytes in payload | (depends) | | Path[0] | byte (4) | Derivation Path Data | 0x8000002c | | Path[1] | byte (4) | Derivation Path Data | 0x8000003c | @@ -280,3 +284,46 @@ All other packets/chunks contain data chunks that are described below | ------- | --------- | ----------- | ------------------------ | | SIG | byte (65) | Signature | | | SW1-SW2 | byte (2) | Return code | see list of return codes | + +### INS_SIGN_PERSONAL_MESSAGE + +#### Command + +| Field | Type | Content | Expected | +| ----- | -------- | ---------------------- | --------- | +| CLA | byte (1) | Application Identifier | 0xE0 | +| INS | byte (1) | Instruction ID | 0x08 | +| P1 | byte (1) | Payload desc | 0x0 = first | +| | | | 0x8 = more | +| | | | | +| P2 | byte (1) | ---- | not used | +| L | byte (1) | Bytes in the payload | (depends) | + +The first packet/chunk includes the derivation path but it can also include some bytes of the message to be signed. + +All other packets/chunks contain data chunks that are described below + +##### First Packet + +| Field | Type | Content | Expected | +| ------- | -------- | -------------------- | -------- | +| Path[0] | byte (4) | Derivation Path Data | 44 | +| Path[1] | byte (4) | Derivation Path Data | 60 | +| Path[2] | byte (4) | Derivation Path Data | ? | +| Path[3] | byte (4) | Derivation Path Data | ? | +| Path[4] | byte (4) | Derivation Path Data | ? | +| Msg size| byte (4) | Message to sign size | ? | +| Msg | bytes... | Message to Sign | | + +##### Other Chunks/Packets + +| Field | Type | Content | Expected | +| ------- | -------- | --------------- | -------- | +| Msg | bytes... | Message to Sign | | + +#### Response + +| Field | Type | Content | Note | +| ------- | --------- | ----------- | ------------------------ | +| SIG | byte (65) | Signature | | +| SW1-SW2 | byte (2) | Return code | see list of return codes | From 2a7aa66b90c82b3c5514f79e7d6f0a769b068ed6 Mon Sep 17 00:00:00 2001 From: Carlos Medeiros Date: Sun, 22 Dec 2024 18:30:04 +0000 Subject: [PATCH 7/7] update docs --- docs/APDUSPEC.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/APDUSPEC.md b/docs/APDUSPEC.md index 17c0dce..f5f4504 100644 --- a/docs/APDUSPEC.md +++ b/docs/APDUSPEC.md @@ -285,6 +285,8 @@ All other packets/chunks contain data chunks that are described below | SIG | byte (65) | Signature | | | SW1-SW2 | byte (2) | Return code | see list of return codes | +--- + ### INS_SIGN_PERSONAL_MESSAGE #### Command @@ -294,7 +296,7 @@ All other packets/chunks contain data chunks that are described below | CLA | byte (1) | Application Identifier | 0xE0 | | INS | byte (1) | Instruction ID | 0x08 | | P1 | byte (1) | Payload desc | 0x0 = first | -| | | | 0x8 = more | +| | | | 0x80 = more | | | | | | | P2 | byte (1) | ---- | not used | | L | byte (1) | Bytes in the payload | (depends) | @@ -312,14 +314,14 @@ All other packets/chunks contain data chunks that are described below | Path[2] | byte (4) | Derivation Path Data | ? | | Path[3] | byte (4) | Derivation Path Data | ? | | Path[4] | byte (4) | Derivation Path Data | ? | -| Msg size| byte (4) | Message to sign size | ? | -| Msg | bytes... | Message to Sign | | +| Msg size| byte (4) | Size of msg to sign | ? | +| Msg | bytes... | Msg to Sign | | ##### Other Chunks/Packets | Field | Type | Content | Expected | | ------- | -------- | --------------- | -------- | -| Msg | bytes... | Message to Sign | | +| Msg | bytes... | Msg to Sign | | #### Response