1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
17 //-----------------------------------------------------------------------------
19 #include "crypto/libpcrypto.h"
20 #include "crypto/asn1utils.h"
25 #include <mbedtls/asn1.h>
26 #include <mbedtls/des.h>
27 #include <mbedtls/aes.h>
28 #include <mbedtls/cmac.h>
29 #include <mbedtls/pk.h>
30 #include <mbedtls/ecdsa.h>
31 #include <mbedtls/sha1.h>
32 #include <mbedtls/sha256.h>
33 #include <mbedtls/sha512.h>
34 #include <mbedtls/ctr_drbg.h>
35 #include <mbedtls/entropy.h>
36 #include <mbedtls/error.h>
37 #include <mbedtls/blowfish.h>
38 #include "libpcrypto.h"
43 void des_encrypt(void *out
, const void *in
, const void *key
) {
44 mbedtls_des_context ctx
;
45 mbedtls_des_setkey_enc(&ctx
, key
);
46 mbedtls_des_crypt_ecb(&ctx
, in
, out
);
47 mbedtls_des_free(&ctx
);
50 void des_decrypt(void *out
, const void *in
, const void *key
) {
51 mbedtls_des_context ctx
;
52 mbedtls_des_setkey_dec(&ctx
, key
);
53 mbedtls_des_crypt_ecb(&ctx
, in
, out
);
54 mbedtls_des_free(&ctx
);
57 void des_encrypt_ecb(void *out
, const void *in
, const int length
, const void *key
) {
58 for (int i
= 0; i
< length
; i
+= 8)
59 des_encrypt((uint8_t *)out
+ i
, (uint8_t *)in
+ i
, key
);
62 void des_decrypt_ecb(void *out
, const void *in
, const int length
, const void *key
) {
63 for (int i
= 0; i
< length
; i
+= 8)
64 des_decrypt((uint8_t *)out
+ i
, (uint8_t *)in
+ i
, key
);
67 void des_encrypt_cbc(void *out
, const void *in
, const int length
, const void *key
, uint8_t *iv
) {
68 mbedtls_des_context ctx
;
69 mbedtls_des_setkey_enc(&ctx
, key
);
70 mbedtls_des_crypt_cbc(&ctx
, MBEDTLS_DES_ENCRYPT
, length
, iv
, in
, out
);
73 void des_decrypt_cbc(void *out
, const void *in
, const int length
, const void *key
, uint8_t *iv
) {
74 mbedtls_des_context ctx
;
75 mbedtls_des_setkey_dec(&ctx
, key
);
76 mbedtls_des_crypt_cbc(&ctx
, MBEDTLS_DES_DECRYPT
, length
, iv
, in
, out
);
79 void des3_encrypt(void *out
, const void *in
, const void *key
, uint8_t keycount
) {
82 des_encrypt(out
, in
, key
);
85 mbedtls_des3_context ctx3
;
86 mbedtls_des3_set2key_enc(&ctx3
, key
);
87 mbedtls_des3_crypt_ecb(&ctx3
, in
, out
);
88 mbedtls_des3_free(&ctx3
);
92 mbedtls_des3_context ctx3
;
93 mbedtls_des3_set3key_enc(&ctx3
, key
);
94 mbedtls_des3_crypt_ecb(&ctx3
, in
, out
);
95 mbedtls_des3_free(&ctx3
);
103 void des3_decrypt(void *out
, const void *in
, const void *key
, uint8_t keycount
) {
106 des_encrypt(out
, in
, key
);
109 mbedtls_des3_context ctx3
;
110 mbedtls_des3_set2key_dec(&ctx3
, key
);
111 mbedtls_des3_crypt_ecb(&ctx3
, in
, out
);
112 mbedtls_des3_free(&ctx3
);
116 mbedtls_des3_context ctx3
;
117 mbedtls_des3_set3key_dec(&ctx3
, key
);
118 mbedtls_des3_crypt_ecb(&ctx3
, in
, out
);
119 mbedtls_des3_free(&ctx3
);
127 // NIST Special Publication 800-38A — Recommendation for block cipher modes of operation: methods and techniques, 2001.
128 int aes_encode(uint8_t *iv
, uint8_t *key
, uint8_t *input
, uint8_t *output
, int length
) {
129 uint8_t iiv
[16] = {0};
134 mbedtls_aes_context aes
;
135 mbedtls_aes_init(&aes
);
136 if (mbedtls_aes_setkey_enc(&aes
, key
, 128)) {
139 if (mbedtls_aes_crypt_cbc(&aes
, MBEDTLS_AES_ENCRYPT
, length
, iiv
, input
, output
)) {
142 mbedtls_aes_free(&aes
);
146 int aes_decode(uint8_t *iv
, uint8_t *key
, uint8_t *input
, uint8_t *output
, int length
) {
147 uint8_t iiv
[16] = {0};
152 mbedtls_aes_context aes
;
153 mbedtls_aes_init(&aes
);
154 if (mbedtls_aes_setkey_dec(&aes
, key
, 128)) {
157 if (mbedtls_aes_crypt_cbc(&aes
, MBEDTLS_AES_DECRYPT
, length
, iiv
, input
, output
)) {
160 mbedtls_aes_free(&aes
);
164 // NIST Special Publication 800-38B — Recommendation for block cipher modes of operation: The CMAC mode for authentication.
165 // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CMAC.pdf
166 int aes_cmac(uint8_t *iv
, uint8_t *key
, uint8_t *input
, uint8_t *mac
, int length
) {
167 memset(mac
, 0x00, 16);
170 return mbedtls_aes_cmac_prf_128(key
, MBEDTLS_AES_BLOCK_SIZE
, input
, length
, mac
);
173 int aes_cmac8(uint8_t *iv
, uint8_t *key
, uint8_t *input
, uint8_t *mac
, int length
) {
174 uint8_t cmac_tmp
[16] = {0};
175 memset(mac
, 0x00, 8);
177 int res
= aes_cmac(iv
, key
, input
, cmac_tmp
, length
);
182 for (int i
= 0; i
< 8; i
++) {
183 mac
[i
] = cmac_tmp
[i
* 2 + 1];
188 static uint8_t fixed_rand_value
[250] = {0};
189 static int fixed_rand(void *rng_state
, unsigned char *output
, size_t len
) {
191 memcpy(output
, fixed_rand_value
, len
);
193 memset(output
, 0x00, len
);
199 int sha1hash(uint8_t *input
, int length
, uint8_t *hash
) {
200 if (!hash
|| !input
) {
204 mbedtls_sha1(input
, length
, hash
);
209 int sha256hash(uint8_t *input
, int length
, uint8_t *hash
) {
210 if (!hash
|| !input
) {
214 mbedtls_sha256_context sctx
;
215 mbedtls_sha256_init(&sctx
);
216 mbedtls_sha256_starts(&sctx
, 0); // SHA-256, not 224
217 mbedtls_sha256_update(&sctx
, input
, length
);
218 mbedtls_sha256_finish(&sctx
, hash
);
219 mbedtls_sha256_free(&sctx
);
224 int sha512hash(uint8_t *input
, int length
, uint8_t *hash
) {
225 if (!hash
|| !input
) {
229 mbedtls_sha512_context sctx
;
230 mbedtls_sha512_init(&sctx
);
231 mbedtls_sha512_starts(&sctx
, 0); //SHA-512, not 384
232 mbedtls_sha512_update(&sctx
, input
, length
);
233 mbedtls_sha512_finish(&sctx
, hash
);
234 mbedtls_sha512_free(&sctx
);
239 static int ecdsa_init_str(mbedtls_ecdsa_context
*ctx
, mbedtls_ecp_group_id curveid
, const char *key_d
, const char *key_x
, const char *key_y
) {
244 mbedtls_ecdsa_init(ctx
);
245 int res
= mbedtls_ecp_group_load(&ctx
->grp
, curveid
);
251 res
= mbedtls_mpi_read_string(&ctx
->d
, 16, key_d
);
257 if (key_x
&& key_y
) {
258 res
= mbedtls_ecp_point_read_string(&ctx
->Q
, 16, key_x
, key_y
);
267 static int ecdsa_init(mbedtls_ecdsa_context
*ctx
, mbedtls_ecp_group_id curveid
, uint8_t *key_d
, uint8_t *key_xy
) {
273 mbedtls_ecdsa_init(ctx
);
274 res
= mbedtls_ecp_group_load(&ctx
->grp
, curveid
);
278 size_t keylen
= (ctx
->grp
.nbits
+ 7) / 8;
280 res
= mbedtls_mpi_read_binary(&ctx
->d
, key_d
, keylen
);
286 res
= mbedtls_ecp_point_read_binary(&ctx
->grp
, &ctx
->Q
, key_xy
, keylen
* 2 + 1);
294 int ecdsa_key_create(mbedtls_ecp_group_id curveid
, uint8_t *key_d
, uint8_t *key_xy
) {
296 mbedtls_ecdsa_context ctx
;
297 res
= ecdsa_init(&ctx
, curveid
, NULL
, NULL
);
301 mbedtls_entropy_context entropy
;
302 mbedtls_ctr_drbg_context ctr_drbg
;
303 const char *pers
= "ecdsaproxmark";
305 mbedtls_entropy_init(&entropy
);
306 mbedtls_ctr_drbg_init(&ctr_drbg
);
308 res
= mbedtls_ctr_drbg_seed(&ctr_drbg
, mbedtls_entropy_func
, &entropy
, (const unsigned char *)pers
, strlen(pers
));
312 res
= mbedtls_ecdsa_genkey(&ctx
, curveid
, mbedtls_ctr_drbg_random
, &ctr_drbg
);
316 size_t keylen
= (ctx
.grp
.nbits
+ 7) / 8;
317 res
= mbedtls_mpi_write_binary(&ctx
.d
, key_d
, keylen
);
321 size_t public_keylen
= 0;
322 uint8_t public_key
[200] = {0};
323 res
= mbedtls_ecp_point_write_binary(&ctx
.grp
, &ctx
.Q
, MBEDTLS_ECP_PF_UNCOMPRESSED
, &public_keylen
, public_key
, sizeof(public_key
));
327 if (public_keylen
!= 1 + 2 * keylen
) { // 0x04 <key x><key y>
331 memcpy(key_xy
, public_key
, public_keylen
);
334 mbedtls_entropy_free(&entropy
);
335 mbedtls_ctr_drbg_free(&ctr_drbg
);
336 mbedtls_ecdsa_free(&ctx
);
340 char *ecdsa_get_error(int ret
) {
341 static char retstr
[300];
342 memset(retstr
, 0x00, sizeof(retstr
));
343 mbedtls_strerror(ret
, retstr
, sizeof(retstr
));
347 int ecdsa_public_key_from_pk(mbedtls_pk_context
*pk
, mbedtls_ecp_group_id curveid
, uint8_t *key
, size_t keylen
) {
349 size_t realkeylen
= 0;
351 mbedtls_ecdsa_context ctx
;
352 mbedtls_ecdsa_init(&ctx
);
354 res
= mbedtls_ecp_group_load(&ctx
.grp
, curveid
);
358 size_t private_keylen
= (ctx
.grp
.nbits
+ 7) / 8;
359 if (keylen
< 1 + 2 * private_keylen
) {
364 res
= mbedtls_ecdsa_from_keypair(&ctx
, mbedtls_pk_ec(*pk
));
368 res
= mbedtls_ecp_point_write_binary(&ctx
.grp
, &ctx
.Q
, MBEDTLS_ECP_PF_UNCOMPRESSED
, &realkeylen
, key
, keylen
);
369 if (realkeylen
!= 1 + 2 * private_keylen
)
372 mbedtls_ecdsa_free(&ctx
);
376 int ecdsa_signature_create(mbedtls_ecp_group_id curveid
, uint8_t *key_d
, uint8_t *key_xy
, uint8_t *input
, int length
, uint8_t *signature
, size_t *signaturelen
, bool hash
) {
380 uint8_t shahash
[32] = {0};
381 res
= sha256hash(input
, length
, shahash
);
385 mbedtls_entropy_context entropy
;
386 mbedtls_ctr_drbg_context ctr_drbg
;
387 const char *pers
= "ecdsaproxmark";
389 mbedtls_entropy_init(&entropy
);
390 mbedtls_ctr_drbg_init(&ctr_drbg
);
392 res
= mbedtls_ctr_drbg_seed(&ctr_drbg
, mbedtls_entropy_func
, &entropy
, (const unsigned char *)pers
, strlen(pers
));
396 mbedtls_ecdsa_context ctx
;
397 res
= ecdsa_init(&ctx
, curveid
, key_d
, key_xy
);
401 res
= mbedtls_ecdsa_write_signature(
404 hash
? shahash
: input
,
405 hash
? sizeof(shahash
) : length
,
408 mbedtls_ctr_drbg_random
,
414 mbedtls_ctr_drbg_free(&ctr_drbg
);
415 mbedtls_ecdsa_free(&ctx
);
419 static int ecdsa_signature_create_test(mbedtls_ecp_group_id curveid
, const char *key_d
, const char *key_x
, const char *key_y
, const char *random
, uint8_t *input
, int length
, uint8_t *signature
, size_t *signaturelen
) {
423 uint8_t shahash
[32] = {0};
424 res
= sha256hash(input
, length
, shahash
);
429 param_gethex_to_eol(random
, 0, fixed_rand_value
, sizeof(fixed_rand_value
), &rndlen
);
431 mbedtls_ecdsa_context ctx
;
432 res
= ecdsa_init_str(&ctx
, curveid
, key_d
, key_x
, key_y
);
436 res
= mbedtls_ecdsa_write_signature(&ctx
, MBEDTLS_MD_SHA256
, shahash
, sizeof(shahash
), signature
, signaturelen
, fixed_rand
, NULL
);
438 mbedtls_ecdsa_free(&ctx
);
442 static int ecdsa_signature_verify_keystr(mbedtls_ecp_group_id curveid
, const char *key_x
, const char *key_y
, uint8_t *input
, int length
, uint8_t *signature
, size_t signaturelen
, bool hash
) {
444 uint8_t shahash
[32] = {0};
445 res
= sha256hash(input
, length
, shahash
);
449 mbedtls_ecdsa_context ctx
;
450 res
= ecdsa_init_str(&ctx
, curveid
, NULL
, key_x
, key_y
);
454 res
= mbedtls_ecdsa_read_signature(
456 hash
? shahash
: input
,
457 hash
? sizeof(shahash
) : length
,
462 mbedtls_ecdsa_free(&ctx
);
466 int ecdsa_signature_verify(mbedtls_ecp_group_id curveid
, uint8_t *key_xy
, uint8_t *input
, int length
, uint8_t *signature
, size_t signaturelen
, bool hash
) {
468 uint8_t shahash
[32] = {0};
470 res
= sha256hash(input
, length
, shahash
);
476 mbedtls_ecdsa_context ctx
;
477 res
= ecdsa_init(&ctx
, curveid
, NULL
, key_xy
);
482 res
= mbedtls_ecdsa_read_signature(
484 hash
? shahash
: input
,
485 hash
? sizeof(shahash
) : length
,
490 mbedtls_ecdsa_free(&ctx
);
494 // take signature bytes, converts to ASN1 signature and tries to verify
495 int ecdsa_signature_r_s_verify(mbedtls_ecp_group_id curveid
, uint8_t *key_xy
, uint8_t *input
, int length
, uint8_t *r_s
, size_t r_s_len
, bool hash
) {
496 uint8_t signature
[MBEDTLS_ECDSA_MAX_LEN
] = {0};
497 size_t signature_len
= 0;
499 // convert r & s to ASN.1 signature
501 mbedtls_mpi_init(&r
);
502 mbedtls_mpi_init(&s
);
503 mbedtls_mpi_read_binary(&r
, r_s
, r_s_len
/ 2);
504 mbedtls_mpi_read_binary(&s
, r_s
+ r_s_len
/ 2, r_s_len
/ 2);
506 int res
= ecdsa_signature_to_asn1(&r
, &s
, signature
, &signature_len
);
511 res
= ecdsa_signature_verify(curveid
, key_xy
, input
, length
, signature
, signature_len
, hash
);
512 mbedtls_mpi_free(&r
);
513 mbedtls_mpi_free(&s
);
518 #define T_PRIVATE_KEY "C477F9F65C22CCE20657FAA5B2D1D8122336F851A508A1ED04E479C34985BF96"
519 #define T_Q_X "B7E08AFDFE94BAD3F1DC8C734798BA1C62B3A0AD1E9EA2A38201CD0889BC7A19"
520 #define T_Q_Y "3603F747959DBF7A4BB226E41928729063ADC7AE43529E61B563BBC606CC5E09"
521 #define T_K "7A1A7E52797FC8CAAA435D2A4DACE39158504BF204FBE19F14DBB427FAEE50AE"
522 #define T_R "2B42F576D07F4165FF65D1F3B1500F81E44C316F1F0B3EF57325B69ACA46104F"
523 #define T_S "DC42C2122D6392CD3E3A993A89502A8198C1886FE69D262C4B329BDB6B63FAF1"
525 int ecdsa_nist_test(bool verbose
) {
527 uint8_t input
[] = "Example of ECDSA with P-256";
528 mbedtls_ecp_group_id curveid
= MBEDTLS_ECP_DP_SECP256R1
;
529 int length
= strlen((char *)input
);
530 uint8_t signature
[300] = {0};
535 PrintAndLogEx(INFO
, "ECDSA NIST test " NOLF
);
538 res
= ecdsa_signature_create_test(curveid
, T_PRIVATE_KEY
, T_Q_X
, T_Q_Y
, T_K
, input
, length
, signature
, &siglen
);
539 // PrintAndLogEx(INFO, "res: %x signature[%x]: %s", (res < 0)? -res : res, siglen, sprint_hex(signature, siglen));
540 if (res
!= PM3_SUCCESS
)
544 uint8_t rval
[300] = {0};
545 uint8_t sval
[300] = {0};
546 res
= ecdsa_asn1_get_signature(signature
, siglen
, rval
, sval
);
551 uint8_t rval_s
[33] = {0};
552 param_gethex_to_eol(T_R
, 0, rval_s
, sizeof(rval_s
), &slen
);
553 uint8_t sval_s
[33] = {0};
554 param_gethex_to_eol(T_S
, 0, sval_s
, sizeof(sval_s
), &slen
);
555 if (strncmp((char *)rval
, (char *)rval_s
, 32) || strncmp((char *)sval
, (char *)sval_s
, 32)) {
556 PrintAndLogEx(NORMAL
, "( " _RED_("R or S check error") " )");
562 res
= ecdsa_signature_verify_keystr(curveid
, T_Q_X
, T_Q_Y
, input
, length
, signature
, siglen
, true);
567 // verify wrong signature
569 res
= ecdsa_signature_verify_keystr(curveid
, T_Q_X
, T_Q_Y
, input
, length
, signature
, siglen
, true);
576 PrintAndLogEx(NORMAL
, "( " _GREEN_("ok") " )");
577 PrintAndLogEx(INFO
, "ECDSA binary signature create/check test " NOLF
);
581 uint8_t key_d
[32] = {0};
582 uint8_t key_xy
[32 * 2 + 2] = {0};
583 memset(signature
, 0x00, sizeof(signature
));
586 res
= ecdsa_key_create(curveid
, key_d
, key_xy
);
590 res
= ecdsa_signature_create(curveid
, key_d
, key_xy
, input
, length
, signature
, &siglen
, true);
594 res
= ecdsa_signature_verify(curveid
, key_xy
, input
, length
, signature
, siglen
, true);
599 res
= ecdsa_signature_verify(curveid
, key_xy
, input
, length
, signature
, siglen
, true);
604 PrintAndLogEx(NORMAL
, "( " _GREEN_("ok") " )");
609 PrintAndLogEx(NORMAL
, "( " _RED_("fail") " )");
613 void bin_xor(uint8_t *d1
, const uint8_t *d2
, size_t len
) {
614 for (size_t i
= 0; i
< len
; i
++)
615 d1
[i
] = d1
[i
] ^ d2
[i
];
618 void AddISO9797M2Padding(uint8_t *ddata
, size_t *ddatalen
, uint8_t *sdata
, size_t sdatalen
, size_t blocklen
) {
619 *ddatalen
= sdatalen
+ 1;
620 *ddatalen
+= blocklen
- *ddatalen
% blocklen
;
621 memset(ddata
, 0, *ddatalen
);
622 memcpy(ddata
, sdata
, sdatalen
);
623 ddata
[sdatalen
] = ISO9797_M2_PAD_BYTE
;
626 size_t FindISO9797M2PaddingDataLen(const uint8_t *data
, size_t datalen
) {
627 for (int i
= datalen
; i
> 0; i
--) {
628 if (data
[i
- 1] == 0x80)
630 if (data
[i
- 1] != 0x00)
637 int blowfish_decrypt(uint8_t *iv
, uint8_t *key
, uint8_t *input
, uint8_t *output
, int length
) {
638 uint8_t iiv
[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
642 mbedtls_blowfish_context blow
;
643 mbedtls_blowfish_init(&blow
);
644 if (mbedtls_blowfish_setkey(&blow
, key
, 64))
647 if (mbedtls_blowfish_crypt_cbc(&blow
, MBEDTLS_BLOWFISH_DECRYPT
, length
, iiv
, input
, output
))
650 mbedtls_blowfish_free(&blow
);
655 // Implementation from http://www.secg.org/sec1-v2.pdf#subsubsection.3.6.1
656 int ansi_x963_sha256(uint8_t *sharedSecret
, size_t sharedSecretLen
, uint8_t *sharedInfo
, size_t sharedInfoLen
, size_t keyDataLen
, uint8_t *keyData
) {
657 // sha256 hash has (practically) no max input len, so skipping that step
659 if (keyDataLen
>= 32 * (pow(2, 32) - 1)) {
663 uint32_t counter
= 0x00000001;
665 for (int i
= 0; i
< (keyDataLen
/ 32); ++i
) {
666 uint8_t *hashMaterial
= calloc(4 + sharedSecretLen
+ sharedInfoLen
, sizeof(uint8_t));
667 memcpy(hashMaterial
, sharedSecret
, sharedSecretLen
);
668 hashMaterial
[sharedSecretLen
] = (counter
>> 24);
669 hashMaterial
[sharedSecretLen
+ 1] = (counter
>> 16) & 0xFF;
670 hashMaterial
[sharedSecretLen
+ 2] = (counter
>> 8) & 0xFF;
671 hashMaterial
[sharedSecretLen
+ 3] = counter
& 0xFF;
672 memcpy(hashMaterial
+ sharedSecretLen
+ 4, sharedInfo
, sharedInfoLen
);
674 uint8_t hash
[32] = {0};
675 sha256hash(hashMaterial
, 4 + sharedSecretLen
+ sharedInfoLen
, hash
);
678 memcpy(keyData
+ (32 * i
), hash
, 32);