]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/emv/emv_roca.c
   1 /* roca.c - ROCA (CVE-2017-15361) fingerprint checker. 
   2  * Written by Rob Stradling (based on https://github.com/crocs-muni/roca/blob/master/roca/detect.py) 
   3  * Copyright (C) 2017-2018 Sectigo Limited 
   4  * modified 2018 iceman  (dropped openssl bignum,  now use mbedtls lib) 
   7  * This program is free software: you can redistribute it and/or modify 
   8  * it under the terms of the GNU General Public License as published by 
   9  * the Free Software Foundation, either version 2 of the License, or 
  10  * (at your option) any later version. 
  12  * This program is distributed in the hope that it will be useful, 
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  * GNU General Public License for more details. 
  17  * You should have received a copy of the GNU General Public License 
  18  * along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  20 //----------------------------------------------------------------------------- 
  22 //----------------------------------------------------------------------------- 
  32 #include "mbedtls/bignum.h" 
  35 static uint8_t g_primes
[ROCA_PRINTS_LENGTH
] = { 
  36         11, 13, 17, 19, 37, 53, 61, 71, 73, 79, 97, 103, 107, 109, 127, 151, 157 
  39 mbedtls_mpi g_prints
[ROCA_PRINTS_LENGTH
]; 
  41 void rocacheck_init(void) { 
  43         for (int i 
= 0; i 
< ROCA_PRINTS_LENGTH
; i
++) 
  44                 mbedtls_mpi_init(&g_prints
[i
]); 
  46         mbedtls_mpi_read_string(&g_prints
[0], 10, "1026"); 
  47         mbedtls_mpi_read_string(&g_prints
[1], 10, "5658"); 
  48         mbedtls_mpi_read_string(&g_prints
[2], 10, "107286"); 
  49         mbedtls_mpi_read_string(&g_prints
[3], 10, "199410"); 
  50         mbedtls_mpi_read_string(&g_prints
[4], 10, "67109890"); 
  51         mbedtls_mpi_read_string(&g_prints
[5], 10, "5310023542746834"); 
  52         mbedtls_mpi_read_string(&g_prints
[6], 10, "1455791217086302986"); 
  53         mbedtls_mpi_read_string(&g_prints
[7], 10, "20052041432995567486"); 
  54         mbedtls_mpi_read_string(&g_prints
[8], 10, "6041388139249378920330"); 
  55         mbedtls_mpi_read_string(&g_prints
[9], 10, "207530445072488465666"); 
  56         mbedtls_mpi_read_string(&g_prints
[10], 10, "79228162521181866724264247298"); 
  57         mbedtls_mpi_read_string(&g_prints
[11], 10, "1760368345969468176824550810518"); 
  58         mbedtls_mpi_read_string(&g_prints
[12], 10, "50079290986288516948354744811034"); 
  59         mbedtls_mpi_read_string(&g_prints
[13], 10, "473022961816146413042658758988474"); 
  60         mbedtls_mpi_read_string(&g_prints
[14], 10, "144390480366845522447407333004847678774"); 
  61         mbedtls_mpi_read_string(&g_prints
[15], 10, "1800793591454480341970779146165214289059119882"); 
  62         mbedtls_mpi_read_string(&g_prints
[16], 10, "126304807362733370595828809000324029340048915994"); 
  65 void rocacheck_cleanup(void) { 
  66         for (int i 
= 0; i 
< ROCA_PRINTS_LENGTH
; i
++) 
  67                 mbedtls_mpi_free(&g_prints
[i
]); 
  70 int bitand_is_zero(     mbedtls_mpi
* a
, mbedtls_mpi
* b 
) { 
  72         for (int i 
= 0; i 
< mbedtls_mpi_bitlen(a
); i
++) { 
  74                 if (mbedtls_mpi_get_bit(a
, i
) && mbedtls_mpi_get_bit(b
, i
)) 
  81 mbedtls_mpi_uint 
mpi_get_uint(const mbedtls_mpi 
*X
) { 
  83         if (X
->n 
== 1 && X
->s 
> 0) { 
  86         printf("ZERRRRO!!!\n"); 
  90 void print_mpi(const char *msg
, int radix
, const mbedtls_mpi 
*X
) { 
  92         char Xchar
[400] = {0}; 
  95         mbedtls_mpi_write_string(X
, radix
, Xchar
, sizeof(Xchar
), &len
);  
  96         printf("%s[%zd] %s\n", msg
, len
, Xchar
);         
  99 bool emv_rocacheck(const unsigned char *buf
, size_t buflen
, bool verbose
) { 
 101         mbedtls_mpi t_modulus
; 
 102         mbedtls_mpi_init(&t_modulus
); 
 108         MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary(&t_modulus
, buf
, buflen
) ); 
 110         for (int i 
= 0; i 
< ROCA_PRINTS_LENGTH
; i
++) { 
 116                 mbedtls_mpi_init(&t_temp
); 
 117                 mbedtls_mpi_init(&t_prime
); 
 118                 mbedtls_mpi_init(&g_one
); 
 120                 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string(&g_one
, 10, "1") ); 
 122                 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int(&t_prime
, &t_prime
, g_primes
[i
]) ); 
 124                 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi(&t_temp
, &t_modulus
, &t_prime
) );  
 126                 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l(&g_one
, mpi_get_uint(&t_temp
)) ); 
 128                 if (bitand_is_zero(&g_one
, &g_prints
[i
])) { 
 130                                 PrintAndLogEx(FAILED
, "No fingerprint found.\n"); 
 134                 mbedtls_mpi_free(&g_one
);                
 135                 mbedtls_mpi_free(&t_temp
); 
 136                 mbedtls_mpi_free(&t_prime
); 
 141                 PrintAndLogEx(SUCCESS
, "Fingerprint found!\n"); 
 144         mbedtls_mpi_free(&t_modulus
); 
 150 int roca_self_test( void ) { 
 153         PrintAndLogEx(INFO
, "ROCA check vulnerability tests" ); 
 156         uint8_t keyp
[] = "\x94\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\
 
 157                         "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\
 
 158                                         "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\
 
 159                                         "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; 
 162         if (emv_rocacheck(keyp
, 64, false)) { 
 163                 PrintAndLogEx(SUCCESS
, "Weak modulus [ %s]", _GREEN_(PASS
) );    
 167                 PrintAndLogEx(FAILED
, "Weak modulus [ %s]", _RED_(FAIL
) ); 
 171         uint8_t keyn
[] = "\x84\x4e\x13\x20\x8a\x28\x0c\x37\xef\xc3\x1c\x31\x14\x48\x5e\x59"\
 
 172                         "\x01\x92\xad\xbb\x8e\x11\xc8\x7c\xad\x60\xcd\xef\x00\x37\xce\x99"\
 
 173                                         "\x27\x83\x30\xd3\xf4\x71\xa2\x53\x8f\xa6\x67\x80\x2e\xd2\xa3\xc4"\
 
 174                                         "\x4a\x8b\x7d\xea\x82\x6e\x88\x8d\x0a\xa3\x41\xfd\x66\x4f\x7f\xa7"; 
 176         if (emv_rocacheck(keyn
, 64, false)) { 
 178                 PrintAndLogEx(FAILED
, "Strong modulus [ %s]", _RED_(FAIL
) ); 
 180                 PrintAndLogEx(SUCCESS
, "Strong modulus [ %s]", _GREEN_(PASS
) );