Skip to content

Commit f63959c

Browse files
Sped0nGOB52
authored andcommitted
feat: use PSA crypto with mbedTLS 4
Signed-off-by: Zhibin (Ryan) Wen <wenzhibin@espressif.com>
1 parent 99ccc23 commit f63959c

3 files changed

Lines changed: 106 additions & 99 deletions

File tree

src/nfc/crypto/aes.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@
1111

1212
#include <M5Utility.hpp>
1313
#include <cstring>
14+
#include <mbedtls/version.h>
15+
16+
#if MBEDTLS_VERSION_MAJOR >= 4
17+
#include <psa/crypto.h>
18+
#include <vector>
19+
#else
1420
#include <mbedtls/aes.h>
21+
#endif
1522

1623
namespace m5 {
1724
namespace nfc {
@@ -29,13 +36,55 @@ void left_shift_128(const uint8_t in[16], uint8_t out[16])
2936
}
3037
}
3138

39+
#if MBEDTLS_VERSION_MAJOR >= 4
40+
bool psa_import_aes_key(psa_key_id_t& key_id, const uint8_t key[16], const psa_algorithm_t alg,
41+
const psa_key_usage_t usage)
42+
{
43+
if (psa_crypto_init() != PSA_SUCCESS) {
44+
M5_LIB_LOGE("PSA crypto init failed");
45+
return false;
46+
}
47+
48+
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
49+
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
50+
psa_set_key_bits(&attributes, 128);
51+
psa_set_key_algorithm(&attributes, alg);
52+
psa_set_key_usage_flags(&attributes, usage);
53+
54+
const psa_status_t status = psa_import_key(&attributes, key, 16, &key_id);
55+
psa_reset_key_attributes(&attributes);
56+
if (status != PSA_SUCCESS) {
57+
M5_LIB_LOGE("PSA AES import failed: %d", static_cast<int>(status));
58+
return false;
59+
}
60+
return true;
61+
}
62+
#endif
63+
3264
} // namespace
3365

3466
bool aes_ecb_encrypt(uint8_t out[16], const uint8_t key[16], const uint8_t in[16])
3567
{
3668
if (!out || !key || !in) {
3769
return false;
3870
}
71+
#if MBEDTLS_VERSION_MAJOR >= 4
72+
psa_key_id_t key_id = PSA_KEY_ID_NULL;
73+
if (!psa_import_aes_key(key_id, key, PSA_ALG_ECB_NO_PADDING, PSA_KEY_USAGE_ENCRYPT)) {
74+
std::memset(out, 0, 16);
75+
return false;
76+
}
77+
78+
size_t out_len = 0;
79+
const psa_status_t status = psa_cipher_encrypt(key_id, PSA_ALG_ECB_NO_PADDING, in, 16, out, 16, &out_len);
80+
psa_destroy_key(key_id);
81+
if (status != PSA_SUCCESS || out_len != 16) {
82+
M5_LIB_LOGE("PSA AES ECB encrypt failed: %d", static_cast<int>(status));
83+
std::memset(out, 0, 16);
84+
return false;
85+
}
86+
return true;
87+
#else
3988
mbedtls_aes_context aes;
4089
mbedtls_aes_init(&aes);
4190
if (mbedtls_aes_setkey_enc(&aes, key, 128) != 0) {
@@ -52,6 +101,7 @@ bool aes_ecb_encrypt(uint8_t out[16], const uint8_t key[16], const uint8_t in[16
52101
}
53102
mbedtls_aes_free(&aes);
54103
return true;
104+
#endif
55105
}
56106

57107
bool aes_cbc_crypt(uint8_t* out, const uint8_t key[16], const uint8_t iv_in[16], const uint8_t* in, const size_t len,
@@ -60,6 +110,50 @@ bool aes_cbc_crypt(uint8_t* out, const uint8_t key[16], const uint8_t iv_in[16],
60110
if (!out || !key || !iv_in || (!in && len)) {
61111
return false;
62112
}
113+
if (len % 16 != 0) {
114+
return false;
115+
}
116+
if (len == 0) {
117+
return true;
118+
}
119+
#if MBEDTLS_VERSION_MAJOR >= 4
120+
psa_key_id_t key_id = PSA_KEY_ID_NULL;
121+
if (!psa_import_aes_key(key_id, key, PSA_ALG_CBC_NO_PADDING,
122+
encrypt ? PSA_KEY_USAGE_ENCRYPT : PSA_KEY_USAGE_DECRYPT)) {
123+
std::memset(out, 0, len);
124+
return false;
125+
}
126+
127+
std::vector<uint8_t> tmp(len + PSA_CIPHER_FINISH_OUTPUT_MAX_SIZE);
128+
129+
psa_cipher_operation_t operation = psa_cipher_operation_init();
130+
psa_status_t status = encrypt ? psa_cipher_encrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING)
131+
: psa_cipher_decrypt_setup(&operation, key_id, PSA_ALG_CBC_NO_PADDING);
132+
if (status == PSA_SUCCESS) {
133+
status = psa_cipher_set_iv(&operation, iv_in, 16);
134+
}
135+
136+
size_t update_len = 0;
137+
if (status == PSA_SUCCESS) {
138+
status = psa_cipher_update(&operation, in, len, tmp.data(), len, &update_len);
139+
}
140+
141+
size_t finish_len = 0;
142+
if (status == PSA_SUCCESS) {
143+
status = psa_cipher_finish(&operation, tmp.data() + update_len, tmp.size() - update_len, &finish_len);
144+
}
145+
146+
psa_cipher_abort(&operation);
147+
psa_destroy_key(key_id);
148+
149+
if (status != PSA_SUCCESS || update_len + finish_len != len) {
150+
M5_LIB_LOGE("PSA AES CBC crypt failed: %d", static_cast<int>(status));
151+
std::memset(out, 0, len);
152+
return false;
153+
}
154+
std::memcpy(out, tmp.data(), len);
155+
return true;
156+
#else
63157
mbedtls_aes_context aes;
64158
mbedtls_aes_init(&aes);
65159
if (encrypt) {
@@ -87,6 +181,7 @@ bool aes_cbc_crypt(uint8_t* out, const uint8_t key[16], const uint8_t iv_in[16],
87181
}
88182
mbedtls_aes_free(&aes);
89183
return true;
184+
#endif
90185
}
91186

92187
bool cmac_subkeys(uint8_t k1[16], uint8_t k2[16], const uint8_t key[16])

src/nfc/isoDEP/desfire_file_system.cpp

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "nfc/apdu/apdu.hpp"
1717
#include <cassert>
1818
#include <cstring>
19-
#include <mbedtls/aes.h>
2019
#include <esp_random.h>
2120
#include <M5Utility.hpp>
2221
#include <algorithm>
@@ -1362,22 +1361,12 @@ bool DESFireFileSystem::authenticateAES(const uint8_t key_no, const uint8_t key[
13621361
m5::nfc::crypto::secure_zero(ek_AB, sizeof(ek_AB));
13631362
};
13641363
{
1365-
mbedtls_aes_context aes;
1366-
mbedtls_aes_init(&aes);
1367-
if (mbedtls_aes_setkey_dec(&aes, key, 128) != 0) {
1368-
M5_LIB_LOGE("AuthAES setkey_dec failed");
1369-
mbedtls_aes_free(&aes);
1370-
wipe();
1371-
return false;
1372-
}
13731364
uint8_t iv[16]{};
1374-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, iv, ek_rndB, rndB) != 0) {
1365+
if (!aes_cbc_crypt(rndB, key, iv, ek_rndB, 16, false)) {
13751366
M5_LIB_LOGE("AuthAES crypt_cbc failed");
1376-
mbedtls_aes_free(&aes);
13771367
wipe();
13781368
return false;
13791369
}
1380-
mbedtls_aes_free(&aes);
13811370
}
13821371

13831372
for (int i = 0; i < 15; ++i) {
@@ -1393,23 +1382,13 @@ bool DESFireFileSystem::authenticateAES(const uint8_t key_no, const uint8_t key[
13931382
std::memcpy(plain_AB + 16, rndB_rot, 16);
13941383

13951384
{
1396-
mbedtls_aes_context aes;
1397-
mbedtls_aes_init(&aes);
1398-
if (mbedtls_aes_setkey_enc(&aes, key, 128) != 0) {
1399-
M5_LIB_LOGE("AuthAES setkey_enc failed");
1400-
mbedtls_aes_free(&aes);
1401-
wipe();
1402-
return false;
1403-
}
14041385
uint8_t iv[16]{};
14051386
std::memcpy(iv, ek_rndB, 16);
1406-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, sizeof(plain_AB), iv, plain_AB, ek_AB) != 0) {
1387+
if (!aes_cbc_crypt(ek_AB, key, iv, plain_AB, sizeof(plain_AB), true)) {
14071388
M5_LIB_LOGE("AuthAES crypt_cbc failed");
1408-
mbedtls_aes_free(&aes);
14091389
wipe();
14101390
return false;
14111391
}
1412-
mbedtls_aes_free(&aes);
14131392
}
14141393

14151394
auto cmd2 = make_native_wrap_command(0xAF, ek_AB, sizeof(ek_AB));
@@ -1427,23 +1406,13 @@ bool DESFireFileSystem::authenticateAES(const uint8_t key_no, const uint8_t key[
14271406

14281407
uint8_t rndA_rot_from_card[16]{};
14291408
{
1430-
mbedtls_aes_context aes;
1431-
mbedtls_aes_init(&aes);
1432-
if (mbedtls_aes_setkey_dec(&aes, key, 128) != 0) {
1433-
M5_LIB_LOGE("AuthAES setkey_dec failed");
1434-
mbedtls_aes_free(&aes);
1435-
wipe();
1436-
return false;
1437-
}
14381409
uint8_t iv[16]{};
14391410
std::memcpy(iv, ek_AB + 16, 16);
1440-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, iv, rx.data(), rndA_rot_from_card) != 0) {
1411+
if (!aes_cbc_crypt(rndA_rot_from_card, key, iv, rx.data(), 16, false)) {
14411412
M5_LIB_LOGE("AuthAES crypt_cbc failed");
1442-
mbedtls_aes_free(&aes);
14431413
wipe();
14441414
return false;
14451415
}
1446-
mbedtls_aes_free(&aes);
14471416
}
14481417

14491418
uint8_t rndA_rot[16]{};

src/nfc/layer/a/nfc_layer_a.cpp

Lines changed: 8 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include <inttypes.h>
1818
#include <M5Utility.hpp>
1919
#include <algorithm>
20-
#include <mbedtls/aes.h>
2120
#include <esp_random.h>
2221
#include <cstring>
2322

@@ -30,6 +29,8 @@ using namespace m5::nfc::ndef;
3029

3130
namespace {
3231

32+
using m5::nfc::crypto::aes_cbc_crypt;
33+
3334
constexpr char dump_sector_header[] =
3435
"Sec[Blk]:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F [Access]\n"
3536
"-----------------------------------------------------------------";
@@ -2249,21 +2250,11 @@ bool NFCLayerA::mifare_plus_authenticateAES(const uint16_t key_no, const mifare:
22492250
uint8_t rndB[16]{};
22502251
{
22512252
uint8_t iv[16]{};
2252-
mbedtls_aes_context aes{};
2253-
mbedtls_aes_init(&aes);
2254-
if (mbedtls_aes_setkey_dec(&aes, key.data(), 128) != 0) {
2255-
M5_LIB_LOGE("AuthAES setkey_dec failed");
2256-
mbedtls_aes_free(&aes);
2257-
m5::nfc::crypto::secure_zero(rndB, sizeof(rndB));
2258-
return false;
2259-
}
2260-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, sizeof(rndB), iv, step1_payload, rndB) != 0) {
2253+
if (!aes_cbc_crypt(rndB, key.data(), iv, step1_payload, sizeof(rndB), false)) {
22612254
M5_LIB_LOGE("AuthAES crypt_cbc failed");
2262-
mbedtls_aes_free(&aes);
22632255
m5::nfc::crypto::secure_zero(rndB, sizeof(rndB));
22642256
return false;
22652257
}
2266-
mbedtls_aes_free(&aes);
22672258
}
22682259

22692260
uint8_t rndA[16]{};
@@ -2283,27 +2274,14 @@ bool NFCLayerA::mifare_plus_authenticateAES(const uint16_t key_no, const mifare:
22832274
cmd2[0] = 0x72;
22842275
{
22852276
uint8_t iv[16]{};
2286-
mbedtls_aes_context aes{};
2287-
mbedtls_aes_init(&aes);
2288-
if (mbedtls_aes_setkey_enc(&aes, key.data(), 128) != 0) {
2289-
M5_LIB_LOGE("AuthAES setkey_enc failed");
2290-
mbedtls_aes_free(&aes);
2291-
m5::nfc::crypto::secure_zero(rndA, sizeof(rndA));
2292-
m5::nfc::crypto::secure_zero(rndB, sizeof(rndB));
2293-
m5::nfc::crypto::secure_zero(rndB_rot, sizeof(rndB_rot));
2294-
m5::nfc::crypto::secure_zero(ab_plain, sizeof(ab_plain));
2295-
return false;
2296-
}
2297-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, sizeof(ab_plain), iv, ab_plain, cmd2 + 1) != 0) {
2277+
if (!aes_cbc_crypt(cmd2 + 1, key.data(), iv, ab_plain, sizeof(ab_plain), true)) {
22982278
M5_LIB_LOGE("AuthAES crypt_cbc failed");
2299-
mbedtls_aes_free(&aes);
23002279
m5::nfc::crypto::secure_zero(rndA, sizeof(rndA));
23012280
m5::nfc::crypto::secure_zero(rndB, sizeof(rndB));
23022281
m5::nfc::crypto::secure_zero(rndB_rot, sizeof(rndB_rot));
23032282
m5::nfc::crypto::secure_zero(ab_plain, sizeof(ab_plain));
23042283
return false;
23052284
}
2306-
mbedtls_aes_free(&aes);
23072285
}
23082286

23092287
rx_len = sizeof(rx);
@@ -2343,29 +2321,15 @@ bool NFCLayerA::mifare_plus_authenticateAES(const uint16_t key_no, const mifare:
23432321
uint8_t ab_resp[32]{};
23442322
{
23452323
uint8_t iv[16]{};
2346-
mbedtls_aes_context aes{};
2347-
mbedtls_aes_init(&aes);
2348-
if (mbedtls_aes_setkey_dec(&aes, key.data(), 128) != 0) {
2349-
M5_LIB_LOGE("AuthAES setkey_dec failed");
2350-
mbedtls_aes_free(&aes);
2351-
m5::nfc::crypto::secure_zero(rndA, sizeof(rndA));
2352-
m5::nfc::crypto::secure_zero(rndB, sizeof(rndB));
2353-
m5::nfc::crypto::secure_zero(rndB_rot, sizeof(rndB_rot));
2354-
m5::nfc::crypto::secure_zero(ab_plain, sizeof(ab_plain));
2355-
m5::nfc::crypto::secure_zero(ab_resp, sizeof(ab_resp));
2356-
return false;
2357-
}
2358-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, sizeof(ab_resp), iv, step2_payload, ab_resp) != 0) {
2324+
if (!aes_cbc_crypt(ab_resp, key.data(), iv, step2_payload, sizeof(ab_resp), false)) {
23592325
M5_LIB_LOGE("AuthAES crypt_cbc failed");
2360-
mbedtls_aes_free(&aes);
23612326
m5::nfc::crypto::secure_zero(rndA, sizeof(rndA));
23622327
m5::nfc::crypto::secure_zero(rndB, sizeof(rndB));
23632328
m5::nfc::crypto::secure_zero(rndB_rot, sizeof(rndB_rot));
23642329
m5::nfc::crypto::secure_zero(ab_plain, sizeof(ab_plain));
23652330
m5::nfc::crypto::secure_zero(ab_resp, sizeof(ab_resp));
23662331
return false;
23672332
}
2368-
mbedtls_aes_free(&aes);
23692333
}
23702334

23712335
uint8_t rndA_rot[16]{};
@@ -2399,31 +2363,19 @@ bool NFCLayerA::mifare_plus_authenticateAES(const uint16_t key_no, const mifare:
23992363

24002364
{
24012365
uint8_t iv[16]{};
2402-
mbedtls_aes_context aes{};
2403-
mbedtls_aes_init(&aes);
2404-
if (mbedtls_aes_setkey_enc(&aes, key.data(), 128) != 0) {
2405-
M5_LIB_LOGE("AuthAES setkey_enc failed");
2406-
mbedtls_aes_free(&aes);
2407-
m5::nfc::crypto::secure_zero(kenc, sizeof(kenc));
2408-
m5::nfc::crypto::secure_zero(kmac, sizeof(kmac));
2409-
return false;
2410-
}
2411-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, sizeof(kenc), iv, kenc, kenc) != 0) {
2366+
if (!aes_cbc_crypt(kenc, key.data(), iv, kenc, sizeof(kenc), true)) {
24122367
M5_LIB_LOGE("AuthAES crypt_cbc failed");
2413-
mbedtls_aes_free(&aes);
24142368
m5::nfc::crypto::secure_zero(kenc, sizeof(kenc));
24152369
m5::nfc::crypto::secure_zero(kmac, sizeof(kmac));
24162370
return false;
24172371
}
24182372
memset(iv, 0, sizeof(iv));
2419-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, sizeof(kmac), iv, kmac, kmac) != 0) {
2373+
if (!aes_cbc_crypt(kmac, key.data(), iv, kmac, sizeof(kmac), true)) {
24202374
M5_LIB_LOGE("AuthAES crypt_cbc failed");
2421-
mbedtls_aes_free(&aes);
24222375
m5::nfc::crypto::secure_zero(kenc, sizeof(kenc));
24232376
m5::nfc::crypto::secure_zero(kmac, sizeof(kmac));
24242377
return false;
24252378
}
2426-
mbedtls_aes_free(&aes);
24272379
}
24282380

24292381
_mfp_session.authenticated = true;
@@ -2564,13 +2516,6 @@ bool NFCLayerA::mifare_plus_read_plain_mac(const uint16_t block, const uint8_t c
25642516

25652517
std::vector<uint8_t> payload(rx + 1, rx + 1 + data_len);
25662518
if (!plain) {
2567-
mbedtls_aes_context aes{};
2568-
mbedtls_aes_init(&aes);
2569-
if (mbedtls_aes_setkey_dec(&aes, _mfp_session.kenc.data(), 128) != 0) {
2570-
M5_LIB_LOGE("AES setkey_dec failed");
2571-
mbedtls_aes_free(&aes);
2572-
return false;
2573-
}
25742519
for (uint8_t i = 0; i < count; ++i) {
25752520
uint8_t iv[16]{};
25762521
const uint8_t ctr = (uint8_t)(r_ctr & 0xFF);
@@ -2579,13 +2524,11 @@ bool NFCLayerA::mifare_plus_read_plain_mac(const uint16_t block, const uint8_t c
25792524
iv[8] = ctr;
25802525
memcpy(&iv[12], _mfp_session.ti.data(), 4);
25812526
uint8_t* blk = payload.data() + i * 16;
2582-
if (mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, 16, iv, blk, blk) != 0) {
2527+
if (!aes_cbc_crypt(blk, _mfp_session.kenc.data(), iv, blk, 16, false)) {
25832528
M5_LIB_LOGE("AES crypt_cbc failed");
2584-
mbedtls_aes_free(&aes);
25852529
return false;
25862530
}
25872531
}
2588-
mbedtls_aes_free(&aes);
25892532
}
25902533

25912534
out.insert(out.end(), payload.begin(), payload.end());

0 commit comments

Comments
 (0)