// sig_out is a pointer to a 0x3c byte buffer which will be filled with the data payload's signature // ap_cert_out is a pointer to a 0x180 byte buffer which will be filled with the temporal AP // certificate // title_id is the title responsible for the signing // data is a pointer to the buffer of data to sign // data_size is the length of the buffer // NG_priv is the device-unique private key to use // NG_id is the device-unique id to use // if NG_priv is nullptr or NG_id is 0, it will use builtin defaults void MakeAPSigAndCert(u8* sig_out, u8* ap_cert_out, u64 title_id, u8* data, u32 data_size, const u8* NG_priv, u32 NG_id) { u8 hash[20]; u8 ap_priv[30]; char signer[64]; char name[64]; if ((NG_id == 0) || (NG_priv == nullptr)) { NG_priv = default_NG_priv; NG_id = DEFAULT_WII_DEVICE_ID; } memset(ap_priv, 0, 0x1e); ap_priv[0x1d] = 1; // setup random ap_priv here if desired // get_rand_bytes(ap_priv, 0x1e); // ap_priv[0] &= 1; memset(ap_cert_out + 4, 0, 60); sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", NG_id); sprintf(name, "AP%016" PRIx64, title_id); MakeBlankSigECCert(ap_cert_out, signer, name, ap_priv, 0); mbedtls_sha1(ap_cert_out + 0x80, 0x100, hash); generate_ecdsa(ap_cert_out + 4, ap_cert_out + 34, NG_priv, hash); mbedtls_sha1(data, data_size, hash); generate_ecdsa(sig_out, sig_out + 30, ap_priv, hash); }
static int32_t handshake(AsyncState *pState, int32_t n) { asyncInvoke *pThis = (asyncInvoke *) pState; Variant v; result_t hr; hr = pThis->m_httpreq->firstHeader("Upgrade", v); if (hr < 0) return hr; if (hr == CALL_RETURN_NULL) return CHECK_ERROR(Runtime::setError("WebSocketHandler: missing Upgrade header.")); if (qstricmp(v.string().c_str(), "websocket")) return CHECK_ERROR(Runtime::setError("WebSocketHandler: invalid Upgrade header.")); hr = pThis->m_httpreq->firstHeader("Sec-WebSocket-Version", v); if (hr < 0) return hr; if (hr == CALL_RETURN_NULL) return CHECK_ERROR(Runtime::setError("WebSocketHandler: missing Sec-WebSocket-Version header.")); if (qstricmp(v.string().c_str(), "13")) return CHECK_ERROR(Runtime::setError("WebSocketHandler: invalid Sec-WebSocket-Version header.")); bool bUpgrade; pThis->m_httpreq->get_upgrade(bUpgrade); if (!bUpgrade) return CHECK_ERROR(Runtime::setError("WebSocketHandler: invalid connection header.")); hr = pThis->m_httpreq->firstHeader("Sec-WebSocket-Key", v); if (hr < 0) return hr; if (hr == CALL_RETURN_NULL) return CHECK_ERROR(Runtime::setError("WebSocketHandler: missing Sec-WebSocket-Key header.")); exlib::string key(v.string()); key.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); unsigned char output[20]; mbedtls_sha1((const unsigned char*)key.c_str(), key.length(), output); exlib::string out; baseEncode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 6, (const char*)output, 20, out); pThis->m_httprep->set_status(101); pThis->m_httprep->addHeader("Sec-WebSocket-Accept", out); pThis->m_httprep->addHeader("Upgrade", "websocket"); pThis->m_httprep->set_upgrade(true); pThis->set(read); return pThis->m_httprep->sendTo(pThis->m_stm, pThis); }
int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) { int ret; unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ unsigned char *c = buf + sizeof(buf); size_t len = 0; memset( buf, 0, sizeof(buf) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); c = buf + sizeof(buf) - 20; len = 20; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), 0, buf + sizeof(buf) - len, len ); }
const bool FrostIdentity::VerifySignature(const std::vector<unsigned char> &data, const std::string &signature) { if(data.size()>0 && signature!="") { std::vector<unsigned char> sigdata; std::vector<unsigned char> hashdata(20,0); unsigned long hashlen=hashdata.size(); int rval; rval=0; if(Base64::Decode(signature,sigdata)==true) { mbedtls_sha1(&data[0],data.size(),&hashdata[0]); m_rsa.len=sigdata.size(); mbedtls_rsa_pkcs1_verify(&m_rsa,0,0,MBEDTLS_RSA_PUBLIC,MBEDTLS_MD_SHA1,hashdata.size(),&hashdata[0],&sigdata[0]); return (rval==0) ? true : false; } else { return false; } } else { return false; } }
const bool FrostIdentity::VerifyAuthor(const std::string &author) { std::vector<std::string> authorparts; std::vector<unsigned char> authorhash(20,0); unsigned long authorhashlen=authorhash.size(); std::string authorhashstr=""; std::vector<unsigned char> publickeydata(m_publickey.begin(),m_publickey.end()); StringFunctions::Split(author,"@",authorparts); if(m_publickey!="" && authorparts.size()==2) { mbedtls_sha1(&publickeydata[0],publickeydata.size(),&authorhash[0]); Base64::Encode(authorhash,authorhashstr); authorhashstr.erase(27); authorhashstr=StringFunctions::Replace(authorhashstr,"/","_"); return (authorhashstr==authorparts[1]); } else { return false; } }
void websocket_create_accept_key(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { size_t olen; unsigned char sha1buf[20]; unsigned char key_src[60]; memcpy(key_src, src, slen); memcpy(key_src + slen, WS_GUID, 36); mbedtls_sha1(key_src, sizeof(key_src), sha1buf); mbedtls_base64_encode(dst, dlen, &olen, sha1buf, sizeof(sha1buf)); dst[olen] = '\0'; }
std::string DolphinAnalytics::MakeUniqueId(const std::string& data) { u8 digest[20]; std::string input = m_unique_id + data; mbedtls_sha1(reinterpret_cast<const u8*>(input.c_str()), input.size(), digest); // Convert to hex string and truncate to 64 bits. std::string out; for (int i = 0; i < 8; ++i) { out += StringFromFormat("%02hhx", digest[i]); } return out; }
static int32_t handshake(AsyncState *pState, int32_t n) { asyncConnect *pThis = (asyncConnect *) pState; if (!qstrcmp(pThis->m_url.c_str(), "wss://", 6)) pThis->m_url = "https://" + pThis->m_url.substr(6); else if (!qstrcmp(pThis->m_url.c_str(), "ws://", 5)) pThis->m_url = "http://" + pThis->m_url.substr(5); else return CHECK_ERROR(Runtime::setError("websocket: unknown protocol")); pThis->m_headers = new Map(); pThis->m_headers->put("Upgrade", "websocket"); pThis->m_headers->put("Connection", "Upgrade"); pThis->m_headers->put("Sec-WebSocket-Version", "13"); if (!pThis->m_origin.empty()) pThis->m_headers->put("Origin", pThis->m_origin.c_str()); char keys[16]; int32_t i; for (i = 0; i < (int32_t)sizeof(keys); i ++) keys[i] = (char)rand(); std::string key; baseEncode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 6, (const char*)&keys, sizeof(keys), key); pThis->m_headers->put("Sec-WebSocket-Key", key); key.append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); unsigned char output[20]; mbedtls_sha1((const unsigned char*)key.data(), key.size(), output); baseEncode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 6, (const char*)output, 20, pThis->m_accept); pThis->set(response); return http_base::request("GET", pThis->m_url.c_str(), NULL, pThis->m_headers, pThis->m_httprep, pThis); }
int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) { int ret; unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ unsigned char *c = buf + sizeof(buf); size_t len = 0; memset( buf, 0, sizeof(buf) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); c = buf + sizeof(buf) - 20; len = 20; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), 0, buf + sizeof(buf) - len, len ); }
JsVar *jswrap_crypto_SHAx(JsVar *message, int shaNum) { JSV_GET_AS_CHAR_ARRAY(msgPtr, msgLen, message); if (!msgPtr) return 0; int bufferSize = 20; if (shaNum>1) bufferSize = shaNum/8; char *outPtr = 0; JsVar *outArr = jsvNewArrayBufferWithPtr((unsigned int)bufferSize, &outPtr); if (!outPtr) { jsError("Not enough memory for result"); return 0; } if (shaNum==1) mbedtls_sha1((unsigned char *)msgPtr, msgLen, (unsigned char *)outPtr); else if (shaNum==224) mbedtls_sha256((unsigned char *)msgPtr, msgLen, (unsigned char *)outPtr, true/*224*/); else if (shaNum==256) mbedtls_sha256((unsigned char *)msgPtr, msgLen, (unsigned char *)outPtr, false/*256*/); else if (shaNum==384) mbedtls_sha512((unsigned char *)msgPtr, msgLen, (unsigned char *)outPtr, true/*384*/); else if (shaNum==512) mbedtls_sha512((unsigned char *)msgPtr, msgLen, (unsigned char *)outPtr, false/*512*/); return outArr; }
int main( void ) { FILE *f; int ret; size_t n, buflen; mbedtls_net_context server_fd; unsigned char *p, *end; unsigned char buf[2048]; unsigned char hash[32]; const char *pers = "dh_client"; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; mbedtls_rsa_context rsa; mbedtls_dhm_context dhm; mbedtls_aes_context aes; mbedtls_net_init( &server_fd ); mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256 ); mbedtls_dhm_init( &dhm ); mbedtls_aes_init( &aes ); mbedtls_ctr_drbg_init( &ctr_drbg ); /* * 1. Setup the RNG */ mbedtls_printf( "\n . Seeding the random number generator" ); fflush( stdout ); mbedtls_entropy_init( &entropy ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } /* * 2. Read the server's public RSA key */ mbedtls_printf( "\n . Reading public key from rsa_pub.txt" ); fflush( stdout ); if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL ) { ret = 1; mbedtls_printf( " failed\n ! Could not open rsa_pub.txt\n" \ " ! Please run rsa_genkey first\n\n" ); goto exit; } mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); if( ( ret = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 || ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_file returned %d\n\n", ret ); goto exit; } rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3; fclose( f ); /* * 3. Initiate the connection */ mbedtls_printf( "\n . Connecting to tcp/%s/%s", SERVER_NAME, SERVER_PORT ); fflush( stdout ); if( ( ret = mbedtls_net_connect( &server_fd, SERVER_NAME, SERVER_PORT, MBEDTLS_NET_PROTO_TCP ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_net_connect returned %d\n\n", ret ); goto exit; } /* * 4a. First get the buffer length */ mbedtls_printf( "\n . Receiving the server's DH parameters" ); fflush( stdout ); memset( buf, 0, sizeof( buf ) ); if( ( ret = mbedtls_net_recv( &server_fd, buf, 2 ) ) != 2 ) { mbedtls_printf( " failed\n ! mbedtls_net_recv returned %d\n\n", ret ); goto exit; } n = buflen = ( buf[0] << 8 ) | buf[1]; if( buflen < 1 || buflen > sizeof( buf ) ) { mbedtls_printf( " failed\n ! Got an invalid buffer length\n\n" ); goto exit; } /* * 4b. Get the DHM parameters: P, G and Ys = G^Xs mod P */ memset( buf, 0, sizeof( buf ) ); if( ( ret = mbedtls_net_recv( &server_fd, buf, n ) ) != (int) n ) { mbedtls_printf( " failed\n ! mbedtls_net_recv returned %d\n\n", ret ); goto exit; } p = buf, end = buf + buflen; if( ( ret = mbedtls_dhm_read_params( &dhm, &p, end ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_dhm_read_params returned %d\n\n", ret ); goto exit; } if( dhm.len < 64 || dhm.len > 512 ) { ret = 1; mbedtls_printf( " failed\n ! Invalid DHM modulus size\n\n" ); goto exit; } /* * 5. Check that the server's RSA signature matches * the SHA-256 hash of (P,G,Ys) */ mbedtls_printf( "\n . Verifying the server's RSA signature" ); fflush( stdout ); p += 2; if( ( n = (size_t) ( end - p ) ) != rsa.len ) { ret = 1; mbedtls_printf( " failed\n ! Invalid RSA signature size\n\n" ); goto exit; } mbedtls_sha1( buf, (int)( p - 2 - buf ), hash ); if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, 0, hash, p ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_rsa_pkcs1_verify returned %d\n\n", ret ); goto exit; } /* * 6. Send our public value: Yc = G ^ Xc mod P */ mbedtls_printf( "\n . Sending own public value to server" ); fflush( stdout ); n = dhm.len; if( ( ret = mbedtls_dhm_make_public( &dhm, (int) dhm.len, buf, n, mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_dhm_make_public returned %d\n\n", ret ); goto exit; } if( ( ret = mbedtls_net_send( &server_fd, buf, n ) ) != (int) n ) { mbedtls_printf( " failed\n ! mbedtls_net_send returned %d\n\n", ret ); goto exit; } /* * 7. Derive the shared secret: K = Ys ^ Xc mod P */ mbedtls_printf( "\n . Shared secret: " ); fflush( stdout ); if( ( ret = mbedtls_dhm_calc_secret( &dhm, buf, sizeof( buf ), &n, mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_dhm_calc_secret returned %d\n\n", ret ); goto exit; } for( n = 0; n < 16; n++ ) mbedtls_printf( "%02x", buf[n] ); /* * 8. Setup the AES-256 decryption key * * This is an overly simplified example; best practice is * to hash the shared secret with a random value to derive * the keying material for the encryption/decryption keys, * IVs and MACs. */ mbedtls_printf( "...\n . Receiving and decrypting the ciphertext" ); fflush( stdout ); mbedtls_aes_setkey_dec( &aes, buf, 256 ); memset( buf, 0, sizeof( buf ) ); if( ( ret = mbedtls_net_recv( &server_fd, buf, 16 ) ) != 16 ) { mbedtls_printf( " failed\n ! mbedtls_net_recv returned %d\n\n", ret ); goto exit; } mbedtls_aes_crypt_ecb( &aes, MBEDTLS_AES_DECRYPT, buf, buf ); buf[16] = '\0'; mbedtls_printf( "\n . Plaintext is \"%s\"\n\n", (char *) buf ); exit: mbedtls_net_free( &server_fd ); mbedtls_aes_free( &aes ); mbedtls_rsa_free( &rsa ); mbedtls_dhm_free( &dhm ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }
pthread_addr_t tls_benchmark_cb(void *args) { int i; int argc; char **argv; unsigned char tmp[200]; char title[TITLE_LEN]; todo_list todo; #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) unsigned char alloc_buf[HEAP_SIZE] = { 0 }; #endif argc = ((struct pthread_arg *)args)->argc; argv = ((struct pthread_arg *)args)->argv; if (argc <= 1) { memset(&todo, 1, sizeof(todo)); } else { memset(&todo, 0, sizeof(todo)); for (i = 1; i < argc; i++) { if (strcmp(argv[i], "md4") == 0) { todo.md4 = 1; } else if (strcmp(argv[i], "md5") == 0) { todo.md5 = 1; } else if (strcmp(argv[i], "ripemd160") == 0) { todo.ripemd160 = 1; } else if (strcmp(argv[i], "sha1") == 0) { todo.sha1 = 1; } else if (strcmp(argv[i], "sha256") == 0) { todo.sha256 = 1; } else if (strcmp(argv[i], "sha512") == 0) { todo.sha512 = 1; } else if (strcmp(argv[i], "arc4") == 0) { todo.arc4 = 1; } else if (strcmp(argv[i], "des3") == 0) { todo.des3 = 1; } else if (strcmp(argv[i], "des") == 0) { todo.des = 1; } else if (strcmp(argv[i], "aes_cbc") == 0) { todo.aes_cbc = 1; } else if (strcmp(argv[i], "aes_gcm") == 0) { todo.aes_gcm = 1; } else if (strcmp(argv[i], "aes_ccm") == 0) { todo.aes_ccm = 1; } else if (strcmp(argv[i], "aes_cmac") == 0) { todo.aes_cmac = 1; } else if (strcmp(argv[i], "des3_cmac") == 0) { todo.des3_cmac = 1; } else if (strcmp(argv[i], "camellia") == 0) { todo.camellia = 1; } else if (strcmp(argv[i], "blowfish") == 0) { todo.blowfish = 1; } else if (strcmp(argv[i], "havege") == 0) { todo.havege = 1; } else if (strcmp(argv[i], "ctr_drbg") == 0) { todo.ctr_drbg = 1; } else if (strcmp(argv[i], "hmac_drbg") == 0) { todo.hmac_drbg = 1; } else if (strcmp(argv[i], "rsa") == 0) { todo.rsa = 1; } else if (strcmp(argv[i], "dhm") == 0) { todo.dhm = 1; } else if (strcmp(argv[i], "ecdsa") == 0) { todo.ecdsa = 1; } else if (strcmp(argv[i], "ecdh") == 0) { todo.ecdh = 1; } else { mbedtls_printf("Unrecognized option: %s\n", argv[i]); mbedtls_printf("Available options: " OPTIONS); } } } mbedtls_printf("\n"); #if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) mbedtls_memory_buffer_alloc_init(alloc_buf, sizeof(alloc_buf)); #endif memset(buf, 0xAA, sizeof(buf)); memset(tmp, 0xBB, sizeof(tmp)); #if defined(MBEDTLS_MD4_C) if (todo.md4) { TIME_AND_TSC("MD4", mbedtls_md4(buf, BUFSIZE, tmp)); } #endif #if defined(MBEDTLS_MD5_C) if (todo.md5) { TIME_AND_TSC("MD5", mbedtls_md5(buf, BUFSIZE, tmp)); } #endif #if defined(MBEDTLS_RIPEMD160_C) if (todo.ripemd160) { TIME_AND_TSC("RIPEMD160", mbedtls_ripemd160(buf, BUFSIZE, tmp)); } #endif #if defined(MBEDTLS_SHA1_C) if (todo.sha1) { TIME_AND_TSC("SHA-1", mbedtls_sha1(buf, BUFSIZE, tmp)); } #endif #if defined(MBEDTLS_SHA256_C) if (todo.sha256) { TIME_AND_TSC("SHA-256", mbedtls_sha256(buf, BUFSIZE, tmp, 0)); } #endif #if defined(MBEDTLS_SHA512_C) if (todo.sha512) { TIME_AND_TSC("SHA-512", mbedtls_sha512(buf, BUFSIZE, tmp, 0)); } #endif #if defined(MBEDTLS_ARC4_C) if (todo.arc4) { mbedtls_arc4_context arc4; mbedtls_arc4_init(&arc4); mbedtls_arc4_setup(&arc4, tmp, 32); TIME_AND_TSC("ARC4", mbedtls_arc4_crypt(&arc4, BUFSIZE, buf, buf)); mbedtls_arc4_free(&arc4); } #endif #if defined(MBEDTLS_DES_C) #if defined(MBEDTLS_CIPHER_MODE_CBC) if (todo.des3) { mbedtls_des3_context des3; mbedtls_des3_init(&des3); mbedtls_des3_set3key_enc(&des3, tmp); TIME_AND_TSC("3DES", mbedtls_des3_crypt_cbc(&des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf)); mbedtls_des3_free(&des3); } if (todo.des) { mbedtls_des_context des; mbedtls_des_init(&des); mbedtls_des_setkey_enc(&des, tmp); TIME_AND_TSC("DES", mbedtls_des_crypt_cbc(&des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf)); mbedtls_des_free(&des); } #endif /* MBEDTLS_CIPHER_MODE_CBC */ #if defined(MBEDTLS_CMAC_C) if (todo.des3_cmac) { unsigned char output[8]; const mbedtls_cipher_info_t *cipher_info; memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_EDE3_ECB); TIME_AND_TSC("3DES-CMAC", mbedtls_cipher_cmac(cipher_info, tmp, 192, buf, BUFSIZE, output)); } #endif /* MBEDTLS_CMAC_C */ #endif /* MBEDTLS_DES_C */ #if defined(MBEDTLS_AES_C) #if defined(MBEDTLS_CIPHER_MODE_CBC) if (todo.aes_cbc) { int keysize; mbedtls_aes_context aes; mbedtls_aes_init(&aes); for (keysize = 128; keysize <= 256; keysize += 64) { mbedtls_snprintf(title, sizeof(title), "AES-CBC-%d", keysize); memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); mbedtls_aes_setkey_enc(&aes, tmp, keysize); TIME_AND_TSC(title, mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf)); } mbedtls_aes_free(&aes); } #endif #if defined(MBEDTLS_GCM_C) if (todo.aes_gcm) { int keysize; mbedtls_gcm_context gcm; mbedtls_gcm_init(&gcm); for (keysize = 128; keysize <= 256; keysize += 64) { mbedtls_snprintf(title, sizeof(title), "AES-GCM-%d", keysize); memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize); TIME_AND_TSC(title, mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp, 12, NULL, 0, buf, buf, 16, tmp)); mbedtls_gcm_free(&gcm); } } #endif #if defined(MBEDTLS_CCM_C) if (todo.aes_ccm) { int keysize; mbedtls_ccm_context ccm; mbedtls_ccm_init(&ccm); for (keysize = 128; keysize <= 256; keysize += 64) { mbedtls_snprintf(title, sizeof(title), "AES-CCM-%d", keysize); memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); mbedtls_ccm_setkey(&ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize); TIME_AND_TSC(title, mbedtls_ccm_encrypt_and_tag(&ccm, BUFSIZE, tmp, 12, NULL, 0, buf, buf, tmp, 16)); mbedtls_ccm_free(&ccm); } } #endif #if defined(MBEDTLS_CMAC_C) if (todo.aes_cmac) { unsigned char output[16]; const mbedtls_cipher_info_t *cipher_info; mbedtls_cipher_type_t cipher_type; int keysize; for (keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB; keysize <= 256; keysize += 64, cipher_type++) { mbedtls_snprintf(title, sizeof(title), "AES-CMAC-%d", keysize); memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); cipher_info = mbedtls_cipher_info_from_type(cipher_type); TIME_AND_TSC(title, mbedtls_cipher_cmac(cipher_info, tmp, keysize, buf, BUFSIZE, output)); } memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); TIME_AND_TSC("AES-CMAC-PRF-128", mbedtls_aes_cmac_prf_128(tmp, 16, buf, BUFSIZE, output)); } #endif /* MBEDTLS_CMAC_C */ #endif /* MBEDTLS_AES_C */ #if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC) if (todo.camellia) { int keysize; mbedtls_camellia_context camellia; mbedtls_camellia_init(&camellia); for (keysize = 128; keysize <= 256; keysize += 64) { mbedtls_snprintf(title, sizeof(title), "CAMELLIA-CBC-%d", keysize); memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); mbedtls_camellia_setkey_enc(&camellia, tmp, keysize); TIME_AND_TSC(title, mbedtls_camellia_crypt_cbc(&camellia, MBEDTLS_CAMELLIA_ENCRYPT, BUFSIZE, tmp, buf, buf)); } mbedtls_camellia_free(&camellia); } #endif #if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC) if (todo.blowfish) { int keysize; mbedtls_blowfish_context blowfish; mbedtls_blowfish_init(&blowfish); for (keysize = 128; keysize <= 256; keysize += 64) { mbedtls_snprintf(title, sizeof(title), "BLOWFISH-CBC-%d", keysize); memset(buf, 0, sizeof(buf)); memset(tmp, 0, sizeof(tmp)); mbedtls_blowfish_setkey(&blowfish, tmp, keysize); TIME_AND_TSC(title, mbedtls_blowfish_crypt_cbc(&blowfish, MBEDTLS_BLOWFISH_ENCRYPT, BUFSIZE, tmp, buf, buf)); } mbedtls_blowfish_free(&blowfish); } #endif #if defined(MBEDTLS_HAVEGE_C) if (todo.havege) { mbedtls_havege_state hs; mbedtls_havege_init(&hs); TIME_AND_TSC("HAVEGE", mbedtls_havege_random(&hs, buf, BUFSIZE)); mbedtls_havege_free(&hs); } #endif #if defined(MBEDTLS_CTR_DRBG_C) if (todo.ctr_drbg) { mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ctr_drbg_init(&ctr_drbg); if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) { mbedtls_exit(1); } TIME_AND_TSC("CTR_DRBG (NOPR)", if (mbedtls_ctr_drbg_random(&ctr_drbg, buf, BUFSIZE) != 0) mbedtls_exit(1)); if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) { mbedtls_exit(1); } mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON); TIME_AND_TSC("CTR_DRBG (PR)", if (mbedtls_ctr_drbg_random(&ctr_drbg, buf, BUFSIZE) != 0) mbedtls_exit(1)); mbedtls_ctr_drbg_free(&ctr_drbg); }
bool CVolumeWiiCrypted::CheckIntegrity() const { // Get partition data size u32 partSizeDiv4; Read(m_VolumeOffset + 0x2BC, 4, (u8*)&partSizeDiv4, false); u64 partDataSize = (u64)Common::swap32(partSizeDiv4) * 4; u32 nClusters = (u32)(partDataSize / 0x8000); for (u32 clusterID = 0; clusterID < nClusters; ++clusterID) { u64 clusterOff = m_VolumeOffset + m_dataOffset + (u64)clusterID * 0x8000; // Read and decrypt the cluster metadata u8 clusterMDCrypted[0x400]; u8 clusterMD[0x400]; u8 IV[16] = {0}; if (!m_pReader->Read(clusterOff, 0x400, clusterMDCrypted)) { NOTICE_LOG(DISCIO, "Integrity Check: fail at cluster %d: could not read metadata", clusterID); return false; } mbedtls_aes_crypt_cbc(m_AES_ctx.get(), MBEDTLS_AES_DECRYPT, 0x400, IV, clusterMDCrypted, clusterMD); // Some clusters have invalid data and metadata because they aren't // meant to be read by the game (for example, holes between files). To // try to avoid reporting errors because of these clusters, we check // the 0x00 paddings in the metadata. // // This may cause some false negatives though: some bad clusters may be // skipped because they are *too* bad and are not even recognized as // valid clusters. To be improved. bool meaningless = false; for (u32 idx = 0x26C; idx < 0x280; ++idx) if (clusterMD[idx] != 0) meaningless = true; if (meaningless) continue; u8 clusterData[0x7C00]; if (!Read((u64)clusterID * 0x7C00, 0x7C00, clusterData, true)) { NOTICE_LOG(DISCIO, "Integrity Check: fail at cluster %d: could not read data", clusterID); return false; } for (u32 hashID = 0; hashID < 31; ++hashID) { u8 hash[20]; mbedtls_sha1(clusterData + hashID * 0x400, 0x400, hash); // Note that we do not use strncmp here if (memcmp(hash, clusterMD + hashID * 20, 20)) { NOTICE_LOG(DISCIO, "Integrity Check: fail at cluster %d: hash %d is invalid", clusterID, hashID); return false; } } } return true; }
static bool CheckIfContentHashMatches(const std::vector<u8>& content, const IOS::ES::Content& info) { std::array<u8, 20> sha1; mbedtls_sha1(content.data(), info.size, sha1.data()); return sha1 == info.sha1; }