From 8aee9468953acd3d4a2d3f65e1910111f50e6945 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 18:20:30 +0300 Subject: [PATCH 01/17] add command `hf cipurse test` --- client/CMakeLists.txt | 1 + client/Makefile | 1 + client/src/cipurse/cipursetest.c | 16 ++++++++++++++++ client/src/cipurse/cipursetest.h | 20 ++++++++++++++++++++ client/src/cmdhfcipurse.c | 8 ++++++++ tools/pm3_tests.sh | 1 + 6 files changed, 47 insertions(+) create mode 100644 client/src/cipurse/cipursetest.c create mode 100644 client/src/cipurse/cipursetest.h diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 5c826790d..a81682337 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -213,6 +213,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/iso7816/iso7816core.c ${PM3_ROOT}/client/src/cipurse/cipursecrypto.c ${PM3_ROOT}/client/src/cipurse/cipursecore.c + ${PM3_ROOT}/client/src/cipurse/cipursetest.c ${PM3_ROOT}/client/src/loclass/cipher.c ${PM3_ROOT}/client/src/loclass/cipherutils.c ${PM3_ROOT}/client/src/loclass/elite_crack.c diff --git a/client/Makefile b/client/Makefile index c0f87e0a7..9ed3feb86 100644 --- a/client/Makefile +++ b/client/Makefile @@ -559,6 +559,7 @@ SRCS = aiddesfire.c \ fido/fidocore.c \ cipurse/cipursecore.c \ cipurse/cipursecrypto.c \ + cipurse/cipursetest.c \ fileutils.c \ flash.c \ generator.c \ diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c new file mode 100644 index 000000000..d10213aac --- /dev/null +++ b/client/src/cipurse/cipursetest.c @@ -0,0 +1,16 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2021 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// tests for crypto +//----------------------------------------------------------------------------- + +#include "cipursetest.h" + +bool CIPURSETest(bool verbose) { + + return true; +} diff --git a/client/src/cipurse/cipursetest.h b/client/src/cipurse/cipursetest.h new file mode 100644 index 000000000..561539eae --- /dev/null +++ b/client/src/cipurse/cipursetest.h @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2021 Merlok +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- +// tests for crypto +//----------------------------------------------------------------------------- + +#ifndef __CIPURSETEST_H__ +#define __CIPURSETEST_H__ + +#include +#include "common.h" +#include "cipurse/cipursecrypto.h" + +bool CIPURSETest(bool verbose); + +#endif /* __CIPURSETEST_H__ */ \ No newline at end of file diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index e0c79bdca..44c6e3bbe 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -25,6 +25,7 @@ #include "cmdhfcipurse.h" #include "cipurse/cipursecore.h" #include "cipurse/cipursecrypto.h" +#include "cipurse/cipursetest.h" #include "ui.h" #include "cmdhf14a.h" #include "cmdtrace.h" @@ -698,6 +699,12 @@ bool CheckCardCipurse(void) { return (res == 0 && sw == 0x9000); } +static int CmdHFCipurseTest(const char *Cmd) { + CIPURSETest(true); + + return PM3_SUCCESS; +} + static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help."}, {"info", CmdHFCipurseInfo, IfPm3Iso14443a, "Get info about CIPURSE tag"}, @@ -706,6 +713,7 @@ static command_t CommandTable[] = { {"write", CmdHFCipurseWriteFile, IfPm3Iso14443a, "Write binary file"}, {"aread", CmdHFCipurseReadFileAttr, IfPm3Iso14443a, "Read file attributes"}, {"delete", CmdHFCipurseDeleteFile, IfPm3Iso14443a, "Delete file"}, + {"test", CmdHFCipurseTest, IfPm3Iso14443a, "Tests"}, {NULL, NULL, 0, NULL} }; diff --git a/tools/pm3_tests.sh b/tools/pm3_tests.sh index 38d66d23f..3ed9ee82b 100755 --- a/tools/pm3_tests.sh +++ b/tools/pm3_tests.sh @@ -491,6 +491,7 @@ while true; do if ! $SLOWTESTS; then if ! CheckExecute "hf iclass loclass test" "$CLIENTBIN -c 'hf iclass loclass --test'" "key diversification (ok)"; then break; fi if ! CheckExecute "emv test" "$CLIENTBIN -c 'emv test'" "Test(s) \[ ok"; then break; fi + if ! CheckExecute "hf cipurse test" "$CLIENTBIN -c 'hf cipurse test'" "Test(s) \[ ok"; then break; fi fi fi echo -e "\n------------------------------------------------------------" From fb9d19e43a889f836493753fbc00c6219b137dc2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 18:43:57 +0300 Subject: [PATCH 02/17] kvv test added --- client/src/cipurse/cipursetest.c | 41 ++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index d10213aac..12a6e47e9 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -10,7 +10,44 @@ #include "cipursetest.h" -bool CIPURSETest(bool verbose) { +#include +#include // memcpy memset +#include "fileutils.h" + +#include "cipurse/cipursecrypto.h" +#include "cipurse/cipursecore.h" + +uint8_t Key[] = CIPURSE_DEFAULT_KEY; +uint8_t KeyKvv[CIPURSE_KVV_LENGTH] = {0x5f, 0xd6, 0x7b, 0xcb}; + +static bool TestKVV(void) { + uint8_t kvv[CIPURSE_KVV_LENGTH] = {0}; + CipurseCGetKVV(Key, kvv); + //PrintAndLogEx(INFO, "kvv: %s", sprint_hex(kvv, 4)); + bool res = memcmp(KeyKvv, kvv, CIPURSE_KVV_LENGTH) == 0; - return true; + if (res) + PrintAndLogEx(INFO, "kvv: " _GREEN_("passed")); + else + PrintAndLogEx(INFO, "kvv: " _RED_("fail")); + + return res; +} + +bool CIPURSETest(bool verbose) { + bool res = true; + + PrintAndLogEx(INFO, "------ " _CYAN_("CIPURSE TESTS") " ------"); + + res = res && TestKVV(); + + + + PrintAndLogEx(INFO, "---------------------------"); + if (res) + PrintAndLogEx(SUCCESS, "\tTest(s) [ %s ]", _GREEN_("ok")); + else + PrintAndLogEx(FAILED, "\tTest(s) [ %s ]", _RED_("fail")); + + return res; } From bbe0fa1a35aa8baf78b36fa469f356acb807f00a Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 19:12:13 +0300 Subject: [PATCH 03/17] fix tests --- client/src/cipurse/cipursetest.c | 4 ++-- client/src/cmdhfcipurse.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 12a6e47e9..c84147002 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -45,9 +45,9 @@ bool CIPURSETest(bool verbose) { PrintAndLogEx(INFO, "---------------------------"); if (res) - PrintAndLogEx(SUCCESS, "\tTest(s) [ %s ]", _GREEN_("ok")); + PrintAndLogEx(SUCCESS, " Test(s) [ %s ]", _GREEN_("ok")); else - PrintAndLogEx(FAILED, "\tTest(s) [ %s ]", _RED_("fail")); + PrintAndLogEx(FAILED, " Test(s) [ %s ]", _RED_("fail")); return res; } diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index 44c6e3bbe..141b78784 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -713,7 +713,7 @@ static command_t CommandTable[] = { {"write", CmdHFCipurseWriteFile, IfPm3Iso14443a, "Write binary file"}, {"aread", CmdHFCipurseReadFileAttr, IfPm3Iso14443a, "Read file attributes"}, {"delete", CmdHFCipurseDeleteFile, IfPm3Iso14443a, "Delete file"}, - {"test", CmdHFCipurseTest, IfPm3Iso14443a, "Tests"}, + {"test", CmdHFCipurseTest, AlwaysAvailable, "Tests"}, {NULL, NULL, 0, NULL} }; From c126f02b95912d76e2bf557db1b999b9beaf81a4 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 19:22:31 +0300 Subject: [PATCH 04/17] added TestISO9797M2 --- client/src/cipurse/cipursetest.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index c84147002..8ef19207f 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -20,6 +20,9 @@ uint8_t Key[] = CIPURSE_DEFAULT_KEY; uint8_t KeyKvv[CIPURSE_KVV_LENGTH] = {0x5f, 0xd6, 0x7b, 0xcb}; +uint8_t TestData[16] = {0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +uint8_t TestDataPadded[16] = {0x11, 0x22, 0x33, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + static bool TestKVV(void) { uint8_t kvv[CIPURSE_KVV_LENGTH] = {0}; CipurseCGetKVV(Key, kvv); @@ -34,12 +37,32 @@ static bool TestKVV(void) { return res; } +static bool TestISO9797M2(void) { + uint8_t data[32] = {0}; + + size_t ddatalen = 0; + AddISO9797M2Padding(data, &ddatalen, TestData, 4, 16); + bool res = (ddatalen == 16); + res = res && (memcmp(data, TestDataPadded, ddatalen) == 0); + + res = res && (FindISO9797M2PaddingDataLen(data, ddatalen) == 4); + + if (res) + PrintAndLogEx(INFO, "ISO9797M2: " _GREEN_("passed")); + else + PrintAndLogEx(INFO, "ISO9797M2: " _RED_("fail")); + + return res; +} + + bool CIPURSETest(bool verbose) { bool res = true; PrintAndLogEx(INFO, "------ " _CYAN_("CIPURSE TESTS") " ------"); res = res && TestKVV(); + res = res && TestISO9797M2(); From 50c40e4ce5498984d150b0b560cf30ab37ccc891 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 19:34:22 +0300 Subject: [PATCH 05/17] added smi test --- client/src/cipurse/cipursetest.c | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 8ef19207f..11eb09853 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -55,6 +55,41 @@ static bool TestISO9797M2(void) { return res; } +static bool TestSMI(void) { + CipurseContext ctx = {0}; + CipurseCClearContext(&ctx); + + bool res = (isCipurseCChannelSecuritySet(&ctx) == false); + + CipurseCChannelSetSecurityLevels(&ctx, CPSPlain, CPSPlain); + res = res && (CipurseCGetSMI(&ctx, false) == 0x00); + res = res && (CipurseCGetSMI(&ctx, true) == 0x01); + + CipurseCChannelSetSecurityLevels(&ctx, CPSPlain, CPSMACed); + res = res && (CipurseCGetSMI(&ctx, false) == 0x04); + res = res && (CipurseCGetSMI(&ctx, true) == 0x05); + + CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); + res = res && (CipurseCGetSMI(&ctx, false) == 0x44); + res = res && (CipurseCGetSMI(&ctx, true) == 0x45); + + CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSEncrypted); + res = res && (CipurseCGetSMI(&ctx, false) == 0x48); + res = res && (CipurseCGetSMI(&ctx, true) == 0x49); + + CipurseCChannelSetSecurityLevels(&ctx, CPSEncrypted, CPSEncrypted); + res = res && (CipurseCGetSMI(&ctx, false) == 0x88); + res = res && (CipurseCGetSMI(&ctx, true) == 0x89); + + if (res) + PrintAndLogEx(INFO, "SMI: " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "SMI: " _RED_("fail")); + + return res; +} + + bool CIPURSETest(bool verbose) { bool res = true; @@ -63,6 +98,7 @@ bool CIPURSETest(bool verbose) { res = res && TestKVV(); res = res && TestISO9797M2(); + res = res && TestSMI(); From 99979c6609e24416232979eab6be6076ff444487 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 19:58:37 +0300 Subject: [PATCH 06/17] added TestAuth --- client/src/cipurse/cipursetest.c | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 11eb09853..49e3d20a6 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -26,13 +26,13 @@ uint8_t TestDataPadded[16] = {0x11, 0x22, 0x33, 0x44, 0x80, 0x00, 0x00, 0x00, 0x static bool TestKVV(void) { uint8_t kvv[CIPURSE_KVV_LENGTH] = {0}; CipurseCGetKVV(Key, kvv); - //PrintAndLogEx(INFO, "kvv: %s", sprint_hex(kvv, 4)); + bool res = memcmp(KeyKvv, kvv, CIPURSE_KVV_LENGTH) == 0; if (res) PrintAndLogEx(INFO, "kvv: " _GREEN_("passed")); else - PrintAndLogEx(INFO, "kvv: " _RED_("fail")); + PrintAndLogEx(ERR, "kvv: " _RED_("fail")); return res; } @@ -50,7 +50,7 @@ static bool TestISO9797M2(void) { if (res) PrintAndLogEx(INFO, "ISO9797M2: " _GREEN_("passed")); else - PrintAndLogEx(INFO, "ISO9797M2: " _RED_("fail")); + PrintAndLogEx(ERR, "ISO9797M2: " _RED_("fail")); return res; } @@ -89,6 +89,48 @@ static bool TestSMI(void) { return res; } +static bool TestAuth(void) { + CipurseContext ctx = {0}; + CipurseCClearContext(&ctx); + + bool res = (isCipurseCChannelSecuritySet(&ctx) == false); + + CipurseCSetKey(&ctx, 1, Key); + res = res && (memcmp(ctx.key, Key, 16) == 0); + res = res && (ctx.keyId == 1); + + uint8_t random[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22}; + CipurseCSetRandomFromPICC(&ctx, random); + res = res && (memcmp(ctx.RP, random, 16) == 0); + res = res && (memcmp(ctx.rP, &random[16], 6) == 0); + + uint8_t hrandom[] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + CipurseCSetRandomHost(&ctx); + res = res && (memcmp(ctx.RT, hrandom, 16) == 0); + res = res && (memcmp(ctx.rT, &hrandom[16], 6) == 0); + + uint8_t authparams[16 + 16 + 6] = {0}; + CipurseCAuthenticateHost(&ctx, authparams); + uint8_t aparamstest[] = {0x12, 0xAA, 0x79, 0xA9, 0x03, 0xC5, 0xB4, 0x6A, 0x27, 0x1B, 0x13, 0xAE, 0x02, 0x50, 0x1C, 0x99, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; + res = res && (memcmp(authparams, aparamstest, sizeof(authparams)) == 0); + + uint8_t ct[] = {0xBE, 0x10, 0x6B, 0xB9, 0xAD, 0x84, 0xBC, 0xE1, 0x9F, 0xAE, 0x0C, 0x62, 0xCC, 0xC7, 0x0D, 0x41}; + res = res && CipurseCCheckCT(&ctx, ct); + PrintAndLogEx(INFO, "SMI: %s", sprint_hex(ctx.CT, 16)); + + CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); + res = res && (isCipurseCChannelSecuritySet(&ctx) == true); + + if (res) + PrintAndLogEx(INFO, "Auth: " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "Auth: " _RED_("fail")); + + return res; +} + + bool CIPURSETest(bool verbose) { @@ -99,6 +141,7 @@ bool CIPURSETest(bool verbose) { res = res && TestKVV(); res = res && TestISO9797M2(); res = res && TestSMI(); + res = res && TestAuth(); From 1832a5b37008eee7ca105ec04ff49b72470f7554 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 20:08:18 +0300 Subject: [PATCH 07/17] added TestMIC --- client/src/cipurse/cipursetest.c | 36 +++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 49e3d20a6..60768142c 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -89,6 +89,30 @@ static bool TestSMI(void) { return res; } +static bool TestMIC(void) { + uint8_t mic[4] = {0}; + + CipurseCGenerateMIC(TestData, 4, mic); + uint8_t valid_mic4[4] = {0xD4, 0x71, 0xA7, 0x73}; + bool res = (memcmp(mic, valid_mic4, 4) == 0); + + res = res && (CipurseCCheckMIC(TestData, 4, mic)); + + CipurseCGenerateMIC(TestData, 6, mic); + uint8_t valid_mic6[4] = {0xAA, 0x90, 0xFC, 0x5A}; + res = res && (memcmp(mic, valid_mic6, 4) == 0); + + res = res && (CipurseCCheckMIC(TestData, 6, mic)); + + if (res) + PrintAndLogEx(INFO, "MIC: " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "MIC: " _RED_("fail")); + + return res; +} + + static bool TestAuth(void) { CipurseContext ctx = {0}; CipurseCClearContext(&ctx); @@ -117,7 +141,6 @@ static bool TestAuth(void) { uint8_t ct[] = {0xBE, 0x10, 0x6B, 0xB9, 0xAD, 0x84, 0xBC, 0xE1, 0x9F, 0xAE, 0x0C, 0x62, 0xCC, 0xC7, 0x0D, 0x41}; res = res && CipurseCCheckCT(&ctx, ct); - PrintAndLogEx(INFO, "SMI: %s", sprint_hex(ctx.CT, 16)); CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); res = res && (isCipurseCChannelSecuritySet(&ctx) == true); @@ -130,8 +153,18 @@ static bool TestAuth(void) { return res; } +// PrintAndLogEx(INFO, "SMI: %s", sprint_hex(ctx.CT, 16)); +//void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); +//void CipurseCCalcMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); +//bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); +//void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt); +//void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen); +//void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen); + +//void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le); +//void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw); bool CIPURSETest(bool verbose) { bool res = true; @@ -141,6 +174,7 @@ bool CIPURSETest(bool verbose) { res = res && TestKVV(); res = res && TestISO9797M2(); res = res && TestSMI(); + res = res && TestMIC(); res = res && TestAuth(); From 7fa4f740f420dd3e01b2ca01a43e12d6bde6b2fb Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 20:22:57 +0300 Subject: [PATCH 08/17] added TestMAC --- client/src/cipurse/cipursetest.c | 54 +++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 60768142c..356b49161 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -20,6 +20,8 @@ uint8_t Key[] = CIPURSE_DEFAULT_KEY; uint8_t KeyKvv[CIPURSE_KVV_LENGTH] = {0x5f, 0xd6, 0x7b, 0xcb}; +uint8_t TestRandom[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22}; + uint8_t TestData[16] = {0x11, 0x22, 0x33, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t TestDataPadded[16] = {0x11, 0x22, 0x33, 0x44, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; @@ -123,10 +125,9 @@ static bool TestAuth(void) { res = res && (memcmp(ctx.key, Key, 16) == 0); res = res && (ctx.keyId == 1); - uint8_t random[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22}; - CipurseCSetRandomFromPICC(&ctx, random); - res = res && (memcmp(ctx.RP, random, 16) == 0); - res = res && (memcmp(ctx.rP, &random[16], 6) == 0); + CipurseCSetRandomFromPICC(&ctx, TestRandom); + res = res && (memcmp(ctx.RP, TestRandom, 16) == 0); + res = res && (memcmp(ctx.rP, &TestRandom[16], 6) == 0); uint8_t hrandom[] = {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}; CipurseCSetRandomHost(&ctx); @@ -153,11 +154,45 @@ static bool TestAuth(void) { return res; } -// PrintAndLogEx(INFO, "SMI: %s", sprint_hex(ctx.CT, 16)); +static bool TestMAC(void) { + CipurseContext ctx = {0}; -//void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); -//void CipurseCCalcMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); -//bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); + // authentication + CipurseCClearContext(&ctx); + CipurseCSetKey(&ctx, 1, Key); + CipurseCSetRandomFromPICC(&ctx, TestRandom); + uint8_t authparams[16 + 16 + 6] = {0}; + CipurseCAuthenticateHost(&ctx, authparams); + uint8_t ct[] = {0xBE, 0x10, 0x6B, 0xB9, 0xAD, 0x84, 0xBC, 0xE1, 0x9F, 0xAE, 0x0C, 0x62, 0xCC, 0xC7, 0x0D, 0x41}; + bool res = CipurseCCheckCT(&ctx, ct); + CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); + res = res && (isCipurseCChannelSecuritySet(&ctx) == true); + + // check MAC + uint8_t mac[8] = {0}; + + CipurseCGenerateMAC(&ctx, TestData, 4, mac); + uint8_t testmac1[8] = {0xAB, 0x5C, 0x86, 0x18, 0x7F, 0x73, 0xEC, 0x4E}; + res = res && (memcmp(mac, testmac1, 8) == 0); + + CipurseCCalcMACPadded(&ctx, TestData, 4, mac); + uint8_t testmac2[8] = {0x9F, 0xE9, 0x54, 0xBF, 0xFC, 0xA0, 0x7D, 0x75}; + res = res && (memcmp(mac, testmac2, 8) == 0); + + CipurseCCalcMACPadded(&ctx, TestData, 4, mac); + uint8_t testmac3[8] = {0x15, 0x6F, 0x08, 0x5C, 0x0F, 0x80, 0xE7, 0x07}; + res = res && (memcmp(mac, testmac3, 8) == 0); + + uint8_t testmac4[8] = {0x0E, 0xF0, 0x70, 0xA6, 0xA1, 0x15, 0x9A, 0xB6}; + res = res && CipurseCCheckMACPadded(&ctx, TestData, 4, testmac4); + + if (res) + PrintAndLogEx(INFO, "channel MAC: " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "channel MAC: " _RED_("fail")); + + return res; +} //void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt); //void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen); @@ -166,6 +201,8 @@ static bool TestAuth(void) { //void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le); //void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw); +// PrintAndLogEx(INFO, "SMI: %s", sprint_hex(ctx.CT, 16)); + bool CIPURSETest(bool verbose) { bool res = true; @@ -176,6 +213,7 @@ bool CIPURSETest(bool verbose) { res = res && TestSMI(); res = res && TestMIC(); res = res && TestAuth(); + res = res && TestMAC(); From 0ca3a5d644f8816b594552f80e0533603093f657 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 20:35:54 +0300 Subject: [PATCH 09/17] added part of TestEncDec --- client/src/cipurse/cipursetest.c | 44 +++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 356b49161..cf2b86e11 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -194,9 +194,47 @@ static bool TestMAC(void) { return res; } -//void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt); //void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen); //void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen); +static bool TestEncDec(void) { + CipurseContext ctx = {0}; + + // authentication + CipurseCClearContext(&ctx); + CipurseCSetKey(&ctx, 1, Key); + CipurseCSetRandomFromPICC(&ctx, TestRandom); + uint8_t authparams[16 + 16 + 6] = {0}; + CipurseCAuthenticateHost(&ctx, authparams); + uint8_t ct[] = {0xBE, 0x10, 0x6B, 0xB9, 0xAD, 0x84, 0xBC, 0xE1, 0x9F, 0xAE, 0x0C, 0x62, 0xCC, 0xC7, 0x0D, 0x41}; + bool res = CipurseCCheckCT(&ctx, ct); + CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); + res = res && (isCipurseCChannelSecuritySet(&ctx) == true); + + // check Encode-Decode + uint8_t dstdata[32] = {0}; + + CipurseCEncryptDecrypt(&ctx, TestData, 16, dstdata, true); + uint8_t tested1[16] = {0x5F, 0x01, 0x18, 0x79, 0xE0, 0x57, 0xA7, 0xE5, 0x34, 0x39, 0x6E, 0x32, 0x62, 0xF2, 0x71, 0x27}; + res = res && (memcmp(dstdata, tested1, 16) == 0); + //PrintAndLogEx(INFO, "SMI: %s", sprint_hex(dstdata, 16)); + + uint8_t tested2[16] = {0xA6, 0x22, 0xB5, 0xCF, 0xE8, 0x6E, 0x67, 0xF4, 0xAA, 0x88, 0xB1, 0x19, 0x87, 0xCF, 0xC9, 0xD2}; + CipurseCEncryptDecrypt(&ctx, tested2, 16, dstdata, false); + res = res && (memcmp(dstdata, TestData, 16) == 0); + + + + + + + + if (res) + PrintAndLogEx(INFO, "channel EncDec: " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "channel EncDec: " _RED_("fail")); + + return res; +} //void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le); //void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw); @@ -214,8 +252,8 @@ bool CIPURSETest(bool verbose) { res = res && TestMIC(); res = res && TestAuth(); res = res && TestMAC(); - - + res = res && TestEncDec(); + res = res && true; PrintAndLogEx(INFO, "---------------------------"); if (res) From 8e822e967760db110d2527536ceea07106555613 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 20:45:14 +0300 Subject: [PATCH 10/17] added TestEncDec --- client/src/cipurse/cipursetest.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index cf2b86e11..f9d5c83e9 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -194,8 +194,6 @@ static bool TestMAC(void) { return res; } -//void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen); -//void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen); static bool TestEncDec(void) { CipurseContext ctx = {0}; @@ -212,22 +210,28 @@ static bool TestEncDec(void) { // check Encode-Decode uint8_t dstdata[32] = {0}; + size_t dstdatalen = 0; CipurseCEncryptDecrypt(&ctx, TestData, 16, dstdata, true); uint8_t tested1[16] = {0x5F, 0x01, 0x18, 0x79, 0xE0, 0x57, 0xA7, 0xE5, 0x34, 0x39, 0x6E, 0x32, 0x62, 0xF2, 0x71, 0x27}; res = res && (memcmp(dstdata, tested1, 16) == 0); - //PrintAndLogEx(INFO, "SMI: %s", sprint_hex(dstdata, 16)); uint8_t tested2[16] = {0xA6, 0x22, 0xB5, 0xCF, 0xE8, 0x6E, 0x67, 0xF4, 0xAA, 0x88, 0xB1, 0x19, 0x87, 0xCF, 0xC9, 0xD2}; CipurseCEncryptDecrypt(&ctx, tested2, 16, dstdata, false); res = res && (memcmp(dstdata, TestData, 16) == 0); + CipurseCChannelEncrypt(&ctx, TestData, 16, dstdata, &dstdatalen); + uint8_t tested3[32] = {0x1E, 0x0C, 0xD1, 0xF5, 0x8E, 0x0B, 0xAE, 0xF0, 0x06, 0xC6, 0xED, 0x73, 0x3F, 0x8A, 0x87, 0xCF, + 0x36, 0xCC, 0xF2, 0xF4, 0x7D, 0x33, 0x50, 0xF1, 0x8E, 0xFF, 0xD1, 0x7D, 0x42, 0x88, 0xD5, 0xEE}; + res = res && (dstdatalen == 32); + res = res && (memcmp(dstdata, tested3, 32) == 0); + uint8_t tested4[32] = {0xC0, 0x42, 0xDB, 0xD9, 0x53, 0xFF, 0x01, 0xE5, 0xCC, 0x49, 0x8C, 0x9C, 0xDA, 0x60, 0x73, 0xA7, + 0xE1, 0xEB, 0x14, 0x69, 0xF6, 0x39, 0xF3, 0xE1, 0x07, 0x03, 0x32, 0xF4, 0x27, 0xF9, 0x48, 0x3D}; + CipurseCChannelDecrypt(&ctx, tested4, 32, dstdata, &dstdatalen); + res = res && (dstdatalen == 16); + res = res && (memcmp(dstdata, TestData, 16) == 0); - - - - if (res) PrintAndLogEx(INFO, "channel EncDec: " _GREEN_("passed")); else From f26b4178f32b83a0286f7eddd580bf66a7c5622f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 20:56:22 +0300 Subject: [PATCH 11/17] part of TestAPDU --- client/src/cipurse/cipursetest.c | 48 ++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index f9d5c83e9..f7e1dc373 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -242,8 +242,52 @@ static bool TestEncDec(void) { //void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, uint8_t *dstdatabuf, bool includeLe, uint8_t Le); //void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw); +static bool TestAPDU(void) { + CipurseContext ctx = {0}; -// PrintAndLogEx(INFO, "SMI: %s", sprint_hex(ctx.CT, 16)); + // authentication + CipurseCClearContext(&ctx); + CipurseCSetKey(&ctx, 1, Key); + CipurseCSetRandomFromPICC(&ctx, TestRandom); + uint8_t authparams[16 + 16 + 6] = {0}; + CipurseCAuthenticateHost(&ctx, authparams); + uint8_t ct[] = {0xBE, 0x10, 0x6B, 0xB9, 0xAD, 0x84, 0xBC, 0xE1, 0x9F, 0xAE, 0x0C, 0x62, 0xCC, 0xC7, 0x0D, 0x41}; + bool res = CipurseCCheckCT(&ctx, ct); + CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); + res = res && (isCipurseCChannelSecuritySet(&ctx) == true); + + // check APDU formatting + sAPDU srcAPDU = {0}; + sAPDU dstAPDU = {0}; + uint8_t dstdata[32] = {0}; + //size_t dstdatalen = 0; + + srcAPDU.CLA = 0x00; + srcAPDU.INS = 0x55; + srcAPDU.P1 = 0x11; + srcAPDU.P2 = 0x22; + srcAPDU.data = TestData; + srcAPDU.Lc = 5; + + CipurseCAPDUReqEncode(&ctx, &srcAPDU, &dstAPDU, dstdata, true, 0x88); + uint8_t test1[] = {0x45, 0x11, 0x22, 0x33, 0x44, 0x00, 0x88, 0x79, 0x2B, 0xB7, 0xDD, 0xD1, 0x69, 0xA6, 0x66}; + res = res && (dstAPDU.Lc == sizeof(test1)); + res = res && (memcmp(dstdata, test1, sizeof(test1)) == 0); + PrintAndLogEx(INFO, "dstAPDU.data: %s", sprint_hex(dstAPDU.data, dstAPDU.Lc)); + + + + + + + + if (res) + PrintAndLogEx(INFO, "apdu: " _GREEN_("passed")); + else + PrintAndLogEx(ERR, "apdu: " _RED_("fail")); + + return res; +} bool CIPURSETest(bool verbose) { bool res = true; @@ -257,7 +301,7 @@ bool CIPURSETest(bool verbose) { res = res && TestAuth(); res = res && TestMAC(); res = res && TestEncDec(); - res = res && true; + res = res && TestAPDU(); PrintAndLogEx(INFO, "---------------------------"); if (res) From f3bdd52cf190da9bab2db121948bc6ce3c7a1419 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 20:59:37 +0300 Subject: [PATCH 12/17] check apdu copy --- client/src/cipurse/cipursetest.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index f7e1dc373..496a39ec1 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -271,6 +271,10 @@ static bool TestAPDU(void) { CipurseCAPDUReqEncode(&ctx, &srcAPDU, &dstAPDU, dstdata, true, 0x88); uint8_t test1[] = {0x45, 0x11, 0x22, 0x33, 0x44, 0x00, 0x88, 0x79, 0x2B, 0xB7, 0xDD, 0xD1, 0x69, 0xA6, 0x66}; + res = res && ((srcAPDU.CLA | 0x04) == dstAPDU.CLA); + res = res && (srcAPDU.INS == dstAPDU.INS); + res = res && (srcAPDU.P1 == dstAPDU.P1); + res = res && (srcAPDU.P2 == dstAPDU.P2); res = res && (dstAPDU.Lc == sizeof(test1)); res = res && (memcmp(dstdata, test1, sizeof(test1)) == 0); PrintAndLogEx(INFO, "dstAPDU.data: %s", sprint_hex(dstAPDU.data, dstAPDU.Lc)); From e0d1656ea14927f008809125ee6845c45d4b9790 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Wed, 23 Jun 2021 21:06:46 +0300 Subject: [PATCH 13/17] add plain apdu encode --- client/src/cipurse/cipursetest.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 496a39ec1..525d67599 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -262,6 +262,7 @@ static bool TestAPDU(void) { uint8_t dstdata[32] = {0}; //size_t dstdatalen = 0; + // MACED APDU srcAPDU.CLA = 0x00; srcAPDU.INS = 0x55; srcAPDU.P1 = 0x11; @@ -281,8 +282,19 @@ static bool TestAPDU(void) { + // Plain APDU + CipurseCChannelSetSecurityLevels(&ctx, CPSPlain, CPSPlain); + CipurseCAPDUReqEncode(&ctx, &srcAPDU, &dstAPDU, dstdata, true, 0x55); + uint8_t test2[] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x00, 0x55}; + res = res && ((srcAPDU.CLA | 0x04) == dstAPDU.CLA); + res = res && (srcAPDU.INS == dstAPDU.INS); + res = res && (srcAPDU.P1 == dstAPDU.P1); + res = res && (srcAPDU.P2 == dstAPDU.P2); + res = res && (dstAPDU.Lc == sizeof(test2)); + res = res && (memcmp(dstdata, test2, sizeof(test2)) == 0); - + // Encrypted APDU + //CipurseCChannelSetSecurityLevels(&ctx, CPSEncrypted, CPSEncrypted); if (res) From 85986e5994919cdb794b11aaac5b15e16a950cf0 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jun 2021 10:18:01 +0300 Subject: [PATCH 14/17] part ot test encrypt --- client/src/cipurse/cipursetest.c | 33 +++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 525d67599..7eb13bbcc 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -260,7 +260,7 @@ static bool TestAPDU(void) { sAPDU srcAPDU = {0}; sAPDU dstAPDU = {0}; uint8_t dstdata[32] = {0}; - //size_t dstdatalen = 0; + size_t dstdatalen = 0; // MACED APDU srcAPDU.CLA = 0x00; @@ -278,23 +278,42 @@ static bool TestAPDU(void) { res = res && (srcAPDU.P2 == dstAPDU.P2); res = res && (dstAPDU.Lc == sizeof(test1)); res = res && (memcmp(dstdata, test1, sizeof(test1)) == 0); - PrintAndLogEx(INFO, "dstAPDU.data: %s", sprint_hex(dstAPDU.data, dstAPDU.Lc)); - + uint16_t sw = 0; + uint8_t test2[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x9D, 0x80, 0xE7, 0xE3, 0x34, 0xE9, 0x97, 0x82, 0xdd, 0xee}; + CipurseCAPDURespDecode(&ctx, test2, sizeof(test2), dstdata, &dstdatalen, &sw); + res = res && (dstdatalen == 6); + res = res && (memcmp(test2, dstdata, dstdatalen) == 0); + res = res && (sw == 0xddee); // Plain APDU CipurseCChannelSetSecurityLevels(&ctx, CPSPlain, CPSPlain); CipurseCAPDUReqEncode(&ctx, &srcAPDU, &dstAPDU, dstdata, true, 0x55); - uint8_t test2[] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x00, 0x55}; + uint8_t test3[] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x00, 0x55}; res = res && ((srcAPDU.CLA | 0x04) == dstAPDU.CLA); res = res && (srcAPDU.INS == dstAPDU.INS); res = res && (srcAPDU.P1 == dstAPDU.P1); res = res && (srcAPDU.P2 == dstAPDU.P2); - res = res && (dstAPDU.Lc == sizeof(test2)); - res = res && (memcmp(dstdata, test2, sizeof(test2)) == 0); + res = res && (dstAPDU.Lc == sizeof(test3)); + res = res && (memcmp(dstdata, test3, sizeof(test3)) == 0); + + uint8_t test4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xcc, 0xdd}; + CipurseCAPDURespDecode(&ctx, test4, sizeof(test4), dstdata, &dstdatalen, &sw); + res = res && (dstdatalen == 6); + res = res && (memcmp(test4, dstdata, dstdatalen) == 0); + res = res && (sw == 0xccdd); // Encrypted APDU - //CipurseCChannelSetSecurityLevels(&ctx, CPSEncrypted, CPSEncrypted); + CipurseCChannelSetSecurityLevels(&ctx, CPSEncrypted, CPSEncrypted); + CipurseCAPDUReqEncode(&ctx, &srcAPDU, &dstAPDU, dstdata, true, 0x55); + uint8_t test5[] = {0x89, 0x7D, 0xED, 0x0D, 0x04, 0x8E, 0xE1, 0x99, 0x08, 0x70, 0x56, 0x7C, 0xEE, 0x67, 0xB3, 0x33, 0x6F, 0x00}; + res = res && ((srcAPDU.CLA | 0x04) == dstAPDU.CLA); + res = res && (srcAPDU.INS == dstAPDU.INS); + res = res && (srcAPDU.P1 == dstAPDU.P1); + res = res && (srcAPDU.P2 == dstAPDU.P2); + res = res && (dstAPDU.Lc == sizeof(test5)); + res = res && (memcmp(dstdata, test5, sizeof(test5)) == 0); + //PrintAndLogEx(INFO, "dstAPDU.data: %s", sprint_hex(dstAPDU.data, dstAPDU.Lc)); if (res) From 8b9271fc7d05920c18ec83786fff3e9766cce8a6 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jun 2021 10:49:36 +0300 Subject: [PATCH 15/17] added frame key checking --- client/src/cipurse/cipursetest.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index 7eb13bbcc..bddc7135f 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -146,6 +146,9 @@ static bool TestAuth(void) { CipurseCChannelSetSecurityLevels(&ctx, CPSMACed, CPSMACed); res = res && (isCipurseCChannelSecuritySet(&ctx) == true); + uint8_t framekey[] = {0xCF, 0x6F, 0x3A, 0x47, 0xFC, 0xAC, 0x8D, 0x38, 0x25, 0x75, 0x8B, 0xFC, 0x8B, 0x61, 0x68, 0xF3}; + res = res && (memcmp(ctx.frameKey, framekey, sizeof(framekey)) == 0); + if (res) PrintAndLogEx(INFO, "Auth: " _GREEN_("passed")); else @@ -175,16 +178,28 @@ static bool TestMAC(void) { uint8_t testmac1[8] = {0xAB, 0x5C, 0x86, 0x18, 0x7F, 0x73, 0xEC, 0x4E}; res = res && (memcmp(mac, testmac1, 8) == 0); + uint8_t framekey1[] = {0x7D, 0x6F, 0x31, 0x40, 0xC8, 0x47, 0xED, 0x3F, 0x0A, 0x21, 0xE6, 0xFB, 0xC7, 0xDB, 0x27, 0xB0}; + res = res && (memcmp(ctx.frameKey, framekey1, sizeof(framekey1)) == 0); + CipurseCCalcMACPadded(&ctx, TestData, 4, mac); uint8_t testmac2[8] = {0x9F, 0xE9, 0x54, 0xBF, 0xFC, 0xA0, 0x7D, 0x75}; res = res && (memcmp(mac, testmac2, 8) == 0); + uint8_t framekey2[] = {0x1E, 0xD4, 0xB6, 0x87, 0x85, 0x93, 0x5B, 0xAF, 0xA9, 0xF2, 0xF0, 0x8F, 0xA9, 0xF0, 0xA5, 0xFB}; + res = res && (memcmp(ctx.frameKey, framekey2, sizeof(framekey2)) == 0); + CipurseCCalcMACPadded(&ctx, TestData, 4, mac); uint8_t testmac3[8] = {0x15, 0x6F, 0x08, 0x5C, 0x0F, 0x80, 0xE7, 0x07}; res = res && (memcmp(mac, testmac3, 8) == 0); + uint8_t framekey3[] = {0x0C, 0x42, 0x93, 0x73, 0x88, 0x8F, 0x63, 0xB3, 0x10, 0x8E, 0xDF, 0xDB, 0xC1, 0x20, 0x63, 0x4C}; + res = res && (memcmp(ctx.frameKey, framekey3, sizeof(framekey3)) == 0); + uint8_t testmac4[8] = {0x0E, 0xF0, 0x70, 0xA6, 0xA1, 0x15, 0x9A, 0xB6}; res = res && CipurseCCheckMACPadded(&ctx, TestData, 4, testmac4); + + uint8_t framekey4[] = {0xA0, 0x65, 0x1A, 0x62, 0x56, 0x5D, 0xD7, 0xC9, 0x32, 0xAE, 0x1D, 0xE0, 0xCF, 0x8D, 0xC1, 0xB9}; + res = res && (memcmp(ctx.frameKey, framekey4, sizeof(framekey4)) == 0); if (res) PrintAndLogEx(INFO, "channel MAC: " _GREEN_("passed")); From aa880239a116de3d03e92430506a3d112351a986 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:39:23 +0300 Subject: [PATCH 16/17] add error check in the crypto stream --- client/src/cipurse/cipursecrypto.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/src/cipurse/cipursecrypto.c b/client/src/cipurse/cipursecrypto.c index e68adc14f..9761fb1e3 100644 --- a/client/src/cipurse/cipursecrypto.c +++ b/client/src/cipurse/cipursecrypto.c @@ -506,6 +506,11 @@ void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdat CipurseCChannelDecrypt(ctx, srcdata, srcdatalen, buf, &buflen); //PrintAndLogEx(INFO, "data plain[%d]: %s", buflen, sprint_hex(buf, buflen)); + if (buflen == 0) { + PrintAndLogEx(ERR, "APDU can't decode crypto stream"); + break; + } + micdatalen = buflen - 2 - CIPURSE_MIC_LENGTH; memcpy(micdata, buf, buflen); memcpy(&micdata[micdatalen], &buf[buflen - 2], 2); From 4ba61c62371ef7f248a760ae0d88d2fb21149e10 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jun 2021 17:39:58 +0300 Subject: [PATCH 17/17] test apdu in the encode mode --- client/src/cipurse/cipursetest.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/client/src/cipurse/cipursetest.c b/client/src/cipurse/cipursetest.c index bddc7135f..56d833690 100644 --- a/client/src/cipurse/cipursetest.c +++ b/client/src/cipurse/cipursetest.c @@ -274,7 +274,7 @@ static bool TestAPDU(void) { // check APDU formatting sAPDU srcAPDU = {0}; sAPDU dstAPDU = {0}; - uint8_t dstdata[32] = {0}; + uint8_t dstdata[256] = {0}; size_t dstdatalen = 0; // MACED APDU @@ -328,8 +328,16 @@ static bool TestAPDU(void) { res = res && (srcAPDU.P2 == dstAPDU.P2); res = res && (dstAPDU.Lc == sizeof(test5)); res = res && (memcmp(dstdata, test5, sizeof(test5)) == 0); - //PrintAndLogEx(INFO, "dstAPDU.data: %s", sprint_hex(dstAPDU.data, dstAPDU.Lc)); + uint8_t test6[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x7E, 0x4B, 0xA0, 0xB7, 0xcc, 0xdd}; + //CipurseCChannelEncrypt(&ctx, test6, sizeof(test6), dstdata, &dstdatalen); + //PrintAndLogEx(INFO, "dstdata[%d]: %s", dstdatalen, sprint_hex(dstdata, dstdatalen)); + + uint8_t test7[] = {0x07, 0xEF, 0x16, 0x91, 0xE7, 0x0F, 0xB5, 0x10, 0x63, 0xCE, 0x66, 0xDB, 0x3B, 0xC6, 0xD4, 0xE0, 0x90, 0x00}; + CipurseCAPDURespDecode(&ctx, test7, sizeof(test7), dstdata, &dstdatalen, &sw); + res = res && (dstdatalen == 8); + res = res && (memcmp(test6, dstdata, dstdatalen) == 0); + res = res && (sw == 0xccdd); if (res) PrintAndLogEx(INFO, "apdu: " _GREEN_("passed"));