int main() { uint8_t a_pub[ECC_BYTES+1]; uint8_t a_pri[ECC_BYTES]; uint8_t b_pub[ECC_BYTES+1]; uint8_t b_pri[ECC_BYTES]; uint8_t a_secret[ECC_BYTES]; uint8_t b_secret[ECC_BYTES]; uint8_t p_signature[ECC_BYTES*2]; uint8_t a_hash[SHA256_BLOCK_SIZE]; uint8_t b_hash[SHA256_BLOCK_SIZE]; SHA256_CTX ctx; int errid = 0; int i=0; /* print ECC_CURVE parameter */ print_parameter(ECC_CURVE); /* make key */ errid = ecc_make_key(a_pub,a_pri); if(errid != 1){ printf("[ecc_make _key] error!!!"); return -1; } printf("A key pair generation completed...\n"); errid = ecc_make_key(b_pub,b_pri); if(errid != 1){ printf("[ecc_make _key] error!!!"); return -1; } printf("B key pair generation completed...\n"); /* compute shared secret */ errid = ecdh_shared_secret(b_pub,a_pri,a_secret); if(errid != 1){ printf("[ecdh_sharedS_secret]error!!!"); return -1; } printf("A shared_secret generation completed...\n"); errid = ecdh_shared_secret(a_pub,b_pri,b_secret); if(errid != 1){ printf("[ecdh_sharedS_secret]error!!!"); return -1; } printf("B shared_secret generation completed...\n"); hash_sha256(a_secret,a_hash); if(errid != 1){ printf("[hash_sha256]error!!!"); return -1; } printf("A shared_secret hash completed...\n"); hash_sha256(b_secret,b_hash); if(errid != 1){ printf("[hash_sha256]error!!!"); return -1; } printf("B shared_secret hash completed...\n"); /* sign */ errid = ecdsa_sign(a_pri,a_hash,p_signature); if(errid != 1){ printf("[ecdsa_sign]error!!!"); return -1; } /* verify */ errid = ecdsa_verify(a_pub,a_hash,p_signature); if(errid != 1){ printf("[ecdsa_verify]error!!!"); return -1; }else{ printf("success \n"); } errid = ecdsa_sign(b_pri,b_hash,p_signature); if(errid != 1){ printf("[ecdsa_sign]error!!!"); return -1; } /* verify */ errid = ecdsa_verify(b_pub,b_hash,p_signature); if(errid != 1){ printf("[ecdsa_verify]error!!!"); return -1; }else{ printf("success \n"); } return 0; }
int signatures_ok(void) { uint32_t codelen = *((uint32_t *)FLASH_META_CODELEN); uint8_t sigindex1, sigindex2, sigindex3; sigindex1 = *((uint8_t *)FLASH_META_SIGINDEX1); sigindex2 = *((uint8_t *)FLASH_META_SIGINDEX2); sigindex3 = *((uint8_t *)FLASH_META_SIGINDEX3); if (sigindex1 < 1 || sigindex1 > PUBKEYS) return 0; // invalid index if (sigindex2 < 1 || sigindex2 > PUBKEYS) return 0; // invalid index if (sigindex3 < 1 || sigindex3 > PUBKEYS) return 0; // invalid index if (sigindex1 == sigindex2) return 0; // duplicate use if (sigindex1 == sigindex3) return 0; // duplicate use if (sigindex2 == sigindex3) return 0; // duplicate use if (ecdsa_verify(&secp256k1, pubkey[sigindex1 - 1], (uint8_t *)FLASH_META_SIG1, (uint8_t *)FLASH_APP_START, codelen) != 0) { // failure return 0; } if (ecdsa_verify(&secp256k1, pubkey[sigindex2 - 1], (uint8_t *)FLASH_META_SIG2, (uint8_t *)FLASH_APP_START, codelen) != 0) { // failure return 0; } if (ecdsa_verify(&secp256k1, pubkey[sigindex3 - 1], (uint8_t *)FLASH_META_SIG3, (uint8_t *)FLASH_APP_START, codelen) != 0) { // failture return 0; } return 1; }
bool ceckey::verify(const uint256 &hash, const std::vector<unsigned char>& vchsig) { if (vchsig.empty()) return false; // new versions of openssl will reject non-canonical der signatures. de/re-serialize first. unsigned char *norm_der = null; ecdsa_sig *norm_sig = ecdsa_sig_new(); const unsigned char* sigptr = &vchsig[0]; assert(norm_sig); if (d2i_ecdsa_sig(&norm_sig, &sigptr, vchsig.size()) == null) { /* as of openssl 1.0.0p d2i_ecdsa_sig frees and nulls the pointer on * error. but openssl's own use of this function redundantly frees the * result. as ecdsa_sig_free(null) is a no-op, and in the absence of a * clear contract for the function behaving the same way is more * conservative. */ ecdsa_sig_free(norm_sig); return false; } int derlen = i2d_ecdsa_sig(norm_sig, &norm_der); ecdsa_sig_free(norm_sig); if (derlen <= 0) return false; // -1 = error, 0 = bad sig, 1 = good bool ret = ecdsa_verify(0, (unsigned char*)&hash, sizeof(hash), norm_der, derlen, pkey) == 1; openssl_free(norm_der); return ret; }
static void bench_ecdsa_verify (void *p) { struct ecdsa_ctx *ctx = p; if (! ecdsa_verify (&ctx->pub, ctx->digest_size, ctx->digest, &ctx->s)) die ("Internal error, _ecdsa_verify failed.\n"); }
int main(){ unsigned char key[48]; unsigned char pkey[96]; unsigned char digest[48]; unsigned char signature[96]; for(int i=0; i<1000; i++){ randombytes(key, 48); randombytes(digest, 48); key[47]=0; p384_32_scalarmult_base(pkey, key); ecdsa_sign(signature, digest, key); if(!ecdsa_verify(signature, digest, pkey)){ printf("Ecdsa failure to verify valid signature\n"); } digest[0]=digest[0]+1; if(ecdsa_verify(signature,digest,pkey)){ printf("Ecdsa failure to reject invalid signature\n"); } } }
// Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys. static bool receive_sig(sptps_t *s, const char *data, uint16_t len) { size_t keylen = ECDH_SIZE; size_t siglen = ecdsa_size(s->hiskey); // Verify length of KEX record. if(len != siglen) return error(s, EIO, "Invalid KEX record length"); // Concatenate both KEX messages, plus tag indicating if it is from the connection originator char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen]; msg[0] = !s->initiator; memcpy(msg + 1, s->hiskex, 1 + 32 + keylen); memcpy(msg + 1 + 33 + keylen, s->mykex, 1 + 32 + keylen); memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen); // Verify signature. if(!ecdsa_verify(s->hiskey, msg, sizeof msg, data)) return error(s, EIO, "Failed to verify SIG record"); // Compute shared secret. char shared[ECDH_SHARED_SIZE]; if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared)) return error(s, EINVAL, "Failed to compute ECDH shared secret"); s->ecdh = NULL; // Generate key material from shared secret. if(!generate_key_material(s, shared, sizeof shared)) return false; free(s->mykex); free(s->hiskex); s->mykex = NULL; s->hiskex = NULL; // Send cipher change record if(s->outstate && !send_ack(s)) return false; // TODO: only set new keys after ACK has been set/received if(s->initiator) { if(!chacha_poly1305_set_key(s->outcipher, s->key + CHACHA_POLY1305_KEYLEN)) return error(s, EINVAL, "Failed to set key"); } else { if(!chacha_poly1305_set_key(s->outcipher, s->key)) return error(s, EINVAL, "Failed to set key"); } return true; }
END_TEST START_TEST(test_verify_speed) { uint8_t sig[64], pub_key33[33], pub_key65[65], msg[256]; size_t i; int res; for (i = 0; i < sizeof(msg); i++) { msg[i] = i * 1103515245; } clock_t t = clock(); memcpy(sig, fromhex("88dc0db6bc5efa762e75fbcc802af69b9f1fcdbdffce748d403f687f855556e610ee8035414099ac7d89cff88a3fa246d332dfa3c78d82c801394112dda039c2"), 64); memcpy(pub_key33, fromhex("024054fd18aeb277aeedea01d3f3986ff4e5be18092a04339dcf4e524e2c0a0974"), 33); memcpy(pub_key65, fromhex("044054fd18aeb277aeedea01d3f3986ff4e5be18092a04339dcf4e524e2c0a09746c7083ed2097011b1223a17a644e81f59aa3de22dac119fd980b36a8ff29a244"), 65); for (i = 0 ; i < 50; i++) { res = ecdsa_verify(pub_key65, sig, msg, sizeof(msg)); ck_assert_int_eq(res, 0); res = ecdsa_verify(pub_key33, sig, msg, sizeof(msg)); ck_assert_int_eq(res, 0); } memcpy(sig, fromhex("067040a2adb3d9deefeef95dae86f69671968a0b90ee72c2eab54369612fd524eb6756c5a1bb662f1175a5fa888763cddc3a07b8a045ef6ab358d8d5d1a9a745"), 64); memcpy(pub_key33, fromhex("03ff45a5561a76be930358457d113f25fac790794ec70317eff3b97d7080d45719"), 33); memcpy(pub_key65, fromhex("04ff45a5561a76be930358457d113f25fac790794ec70317eff3b97d7080d457196235193a15778062ddaa44aef7e6901b781763e52147f2504e268b2d572bf197"), 65); for (i = 0 ; i < 50; i++) { res = ecdsa_verify(pub_key65, sig, msg, sizeof(msg)); ck_assert_int_eq(res, 0); res = ecdsa_verify(pub_key33, sig, msg, sizeof(msg)); ck_assert_int_eq(res, 0); } printf("Verifying speed: %0.2f sig/s\n", 200.0f / ((float)(clock() - t) / CLOCKS_PER_SEC)); }
int main(int argc, char * argv[]) { uint8_t hash[SHA256_DIGEST_LENGTH] = {0}; NN_DIGIT signature_r[NUMWORDS], signature_s[NUMWORDS]; NN_DIGIT privKey[NUMWORDS]; point_t pubKey; uint8_t data [52] = { 1, 2, 3, 4, 5 }; SHA256_CTX ctx; memset(privKey, 0, NUMBYTES); memset(&pubKey, 0, sizeof(pubKey)); memset(signature_r, 0, NUMBYTES); memset(signature_s, 0, NUMBYTES); SHA256_Init(&ctx); SHA256_Update(&ctx, data, 52); SHA256_Final(hash, &ctx); ecc_init(); ecc_gen_private_key(privKey); ecc_gen_pub_key(privKey, &pubKey); ecdsa_init(&pubKey); ecdsa_sign(hash, signature_r, signature_s, privKey); assert(ecdsa_verify(hash, signature_r, signature_s, &pubKey) == 1); signature_r[0] ^= 0xff; assert(ecdsa_verify(hash, signature_r, signature_s, &pubKey) != 1); return 0; }
static void verify_signature(u8* ptr, fileinfo* info, u8* hash, u8** s, u8** r) { u64 sig_len; sig_len = be64(ptr + info->meta_offset + 0x60); *r = ptr + sig_len; *s = *r + 21; sha1(ptr, sig_len, hash); printf("Signature\n"); if (ecdsa_verify(hash, *r, *s)) printf(" Status: OK\n"); else printf(" Status: FAIL\n"); }
// return 1 if certificate is valid, 0 otherwise unsigned char read_certificate(unsigned int *id, char *cname, char time[TIME_BUFFER_SIZE], char valid[TIME_BUFFER_SIZE], unsigned char auth_key[SMQV_PKEY_SIZE], unsigned char token_key[MSS_PKEY_SIZE], unsigned char cert_signature[ECDSA_SIGNATURE_SIZE], const unsigned char ca_pkey[ECDSA_PKEY_SIZE], const unsigned char certificate[CERTIFICATE_MAX_SIZE]) { unsigned int index = 0; int certificate_size = CERTIFICATE_MAX_SIZE; unsigned char buffer[CERTIFICATE_MAX_SIZE]; char t_now[TIME_BUFFER_SIZE]; now(&t_now); memset(buffer, 0, CERTIFICATE_MAX_SIZE); base64decode(certificate, strlen(certificate), buffer, &certificate_size); cert_split_info(buffer, id, cname, time, valid, auth_key, token_key, cert_signature); unsigned char cert_digest[2 * MSS_SEC_LVL]; index = cert_append_info(buffer, *id, cname, time, valid, auth_key, token_key); sponge_hash(buffer, index, cert_digest, 2 * MSS_SEC_LVL); // verify [(id || cname || time || valid || auth_key || token_key), csr_signature, token_key] return compare_dates(t_now, time) <= 0 && compare_dates(t_now, valid) >= 0 && ecdsa_verify(ca_pkey, cert_digest, cert_signature); }
int edata_check_ecdsa(u8 *edata_buf) { u8 sha1_hash[20]; int retv; printf("EDATA ID: %s\n", (char*)(edata_buf+0x10)); ecdsa_set_curve(&ecdsa_app); ecdsa_set_pub(pubkey_edat_x, pubkey_edat_y); SHA1(edata_buf, 0x58, sha1_hash); retv = ecdsa_verify(sha1_hash, edata_buf+0x58, edata_buf+0x6c); if(retv==0){ //printf("ECDSA verify passed!\n"); }else{ printf("edata_check_ecdsa: ECDSA verify failed!\n"); } return retv; }
int main() { unsigned char skey[ECDSA_SKEY_SIZE], pkey[ECDSA_PKEY_SIZE], digest[ECDSA_DIGEST_SIZE], signature[ECDSA_SIGNATURE_SIZE]; printf("ECDSA key generation... "); ecdsa_keygen(skey, pkey); printf("done!\n"); Display("ECDSA skey:", skey, ECDSA_SKEY_SIZE); Display("ECDSA pkey:", pkey, ECDSA_PKEY_SIZE); printf("---------------\n"); Display("digest:", digest, ECDSA_DIGEST_SIZE); printf("ECDSA signature... "); ecdsa_sign(skey, digest, signature); printf("done!\n"); Display("signature:", signature, ECDSA_SIGNATURE_SIZE); printf("ECDSA verification... \n"); if(ecdsa_verify(pkey, digest, signature)) printf("ECDSA - OK\n"); else printf("ECDSA - FAIL\n"); return 0; }
static void verify_signature(void) { u8 *r, *s; u8 hash[20]; u64 sig_len; sig_len = be64(ptr + meta_offset + 0x60); r = ptr + sig_len; s = r + 21; sha1(ptr, sig_len, hash); printf("Signature\n"); if (ecdsa_verify(hash, r, s)) printf(" Status: OK\n"); else printf(" Status: FAIL\n"); printf("\n"); }
/*---------------------------------------------------------------------------*/ static void abc_recv(struct abc_conn *c) { printf("Message received.\n"); msg_header_t * header; uint8_t *data; uint16_t data_len; char i; header = (msg_header_t *)(packetbuf_dataptr()); data_len = ntoh_uint16(&header->data_len); data = (uint8_t *)(header + 1); i = ecdsa_verify(data, data_len, header->r, header->s, &pbkey_alice); if(i==1) { leds_toggle(LEDS_GREEN); } else { leds_toggle(LEDS_RED); } }
bool KeyPair::Verify(const Signature& in, const Digest& hash) { return ecdsa_verify(publicKey, hash.Byte, in.Byte); }
void test_main (void) { unsigned i; struct knuth_lfib_ctx rctx; struct dsa_signature signature; struct tstring *digest; knuth_lfib_init (&rctx, 4711); dsa_signature_init (&signature); digest = SHEX (/* sha256("abc") */ "BA7816BF 8F01CFEA 414140DE 5DAE2223" "B00361A3 96177A9C B410FF61 F20015AD"); for (i = 0; ecc_curves[i]; i++) { const struct ecc_curve *ecc = ecc_curves[i]; struct ecc_point pub; struct ecc_scalar key; if (verbose) fprintf (stderr, "Curve %d\n", ecc->bit_size); ecc_point_init (&pub, ecc); ecc_scalar_init (&key, ecc); ecdsa_generate_keypair (&pub, &key, &rctx, (nettle_random_func *) knuth_lfib_random); if (verbose) { gmp_fprintf (stderr, "Public key:\nx = %Nx\ny = %Nx\n", pub.p, ecc->size, pub.p + ecc->size, ecc->size); gmp_fprintf (stderr, "Private key: %Nx\n", key.p, ecc->size); } if (!ecc_valid_p (&pub)) die ("ecdsa_generate_keypair produced an invalid point.\n"); ecdsa_sign (&key, &rctx, (nettle_random_func *) knuth_lfib_random, digest->length, digest->data, &signature); if (!ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify failed.\n"); digest->data[3] ^= 17; if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid digest.\n"); digest->data[3] ^= 17; mpz_combit (signature.r, 117); if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid signature.r.\n"); mpz_combit (signature.r, 117); mpz_combit (signature.s, 93); if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid signature.s.\n"); ecc_point_clear (&pub); ecc_scalar_clear (&key); } dsa_signature_clear (&signature); }
static int _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, const gnutls_datum_t * vdata, const gnutls_datum_t * signature, const gnutls_pk_params_st * pk_params) { int ret; unsigned int hash_len; bigint_t tmp[2] = { NULL, NULL }; switch (algo) { case GNUTLS_PK_EC: /* ECDSA */ { struct ecc_point pub; struct dsa_signature sig; int curve_id = pk_params->flags; const struct ecc_curve *curve; curve = get_supported_curve(curve_id); if (curve == NULL) return gnutls_assert_val (GNUTLS_E_ECC_UNSUPPORTED_CURVE); ret = _gnutls_decode_ber_rs(signature, &tmp[0], &tmp[1]); if (ret < 0) return gnutls_assert_val(ret); ret = _ecc_params_to_pubkey(pk_params, &pub, curve); if (ret < 0) { gnutls_assert(); goto cleanup; } memcpy(&sig.r, tmp[0], sizeof(sig.r)); memcpy(&sig.s, tmp[1], sizeof(sig.s)); _gnutls_dsa_q_to_hash(algo, pk_params, &hash_len); if (hash_len > vdata->size) hash_len = vdata->size; ret = ecdsa_verify(&pub, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert(); ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; } else ret = 0; ecc_point_clear(&pub); break; } case GNUTLS_PK_DSA: { struct dsa_public_key pub; struct dsa_signature sig; ret = _gnutls_decode_ber_rs(signature, &tmp[0], &tmp[1]); if (ret < 0) { gnutls_assert(); goto cleanup; } memset(&pub, 0, sizeof(pub)); _dsa_params_to_pubkey(pk_params, &pub); memcpy(&sig.r, tmp[0], sizeof(sig.r)); memcpy(&sig.s, tmp[1], sizeof(sig.s)); _gnutls_dsa_q_to_hash(algo, pk_params, &hash_len); if (hash_len > vdata->size) hash_len = vdata->size; ret = _dsa_verify(&pub, hash_len, vdata->data, &sig); if (ret == 0) { gnutls_assert(); ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; } else ret = 0; break; } case GNUTLS_PK_RSA: { struct rsa_public_key pub; _rsa_params_to_pubkey(pk_params, &pub); if (signature->size != pub.size) return gnutls_assert_val (GNUTLS_E_PK_SIG_VERIFY_FAILED); ret = _gnutls_mpi_scan_nz(&tmp[0], signature->data, signature->size); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = rsa_pkcs1_verify(&pub, vdata->size, vdata->data, TOMPZ(tmp[0])); if (ret == 0) ret = gnutls_assert_val (GNUTLS_E_PK_SIG_VERIFY_FAILED); else ret = 0; break; } default: gnutls_assert(); ret = GNUTLS_E_INTERNAL_ERROR; goto cleanup; } cleanup: _gnutls_mpi_release(&tmp[0]); _gnutls_mpi_release(&tmp[1]); return ret; }
int main(int argc, char *argv[]) { ecdsa_t *key1, *key2; ecdh_t *ecdh1, *ecdh2; sptps_t sptps1, sptps2; char buf1[4096], buf2[4096], buf3[4096]; double duration = argc > 1 ? atof(argv[1]) : 10; crypto_init(); randomize(buf1, sizeof buf1); randomize(buf2, sizeof buf2); randomize(buf3, sizeof buf3); // Key generation fprintf(stderr, "Generating keys for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) ecdsa_free(ecdsa_generate()); fprintf(stderr, "%17.2lf op/s\n", rate); key1 = ecdsa_generate(); key2 = ecdsa_generate(); // Ed25519 signatures fprintf(stderr, "Ed25519 sign for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) if(!ecdsa_sign(key1, buf1, 256, buf2)) return 1; fprintf(stderr, "%20.2lf op/s\n", rate); fprintf(stderr, "Ed25519 verify for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) if(!ecdsa_verify(key1, buf1, 256, buf2)) { fprintf(stderr, "Signature verification failed\n"); return 1; } fprintf(stderr, "%18.2lf op/s\n", rate); ecdh1 = ecdh_generate_public(buf1); fprintf(stderr, "ECDH for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) { ecdh2 = ecdh_generate_public(buf2); if(!ecdh2) return 1; if(!ecdh_compute_shared(ecdh2, buf1, buf3)) return 1; } fprintf(stderr, "%28.2lf op/s\n", rate); ecdh_free(ecdh1); // SPTPS authentication phase int fd[2]; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fd)) { fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); return 1; } struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}}; fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) { sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); while(poll(pfd, 2, 0)) { if(pfd[0].revents) receive_data(&sptps1); if(pfd[1].revents) receive_data(&sptps2); } sptps_stop(&sptps1); sptps_stop(&sptps2); } fprintf(stderr, "%10.2lf op/s\n", rate * 2); // SPTPS data sptps_start(&sptps1, fd + 0, true, false, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, false, key2, key1, "sptps_speed", 11, send_data, receive_record); while(poll(pfd, 2, 0)) { if(pfd[0].revents) receive_data(&sptps1); if(pfd[1].revents) receive_data(&sptps2); } fprintf(stderr, "SPTPS/TCP transmit for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) { if(!sptps_send_record(&sptps1, 0, buf1, 1451)) abort(); receive_data(&sptps2); } rate *= 2 * 1451 * 8; if(rate > 1e9) fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); else if(rate > 1e6) fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); else if(rate > 1e3) fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); sptps_stop(&sptps1); sptps_stop(&sptps2); // SPTPS datagram authentication phase close(fd[0]); close(fd[1]); if(socketpair(AF_UNIX, SOCK_DGRAM, 0, fd)) { fprintf(stderr, "Could not create a UNIX socket pair: %s\n", sockstrerror(sockerrno)); return 1; } fprintf(stderr, "SPTPS/UDP authenticate for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) { sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); while(poll(pfd, 2, 0)) { if(pfd[0].revents) receive_data(&sptps1); if(pfd[1].revents) receive_data(&sptps2); } sptps_stop(&sptps1); sptps_stop(&sptps2); } fprintf(stderr, "%10.2lf op/s\n", rate * 2); // SPTPS datagram data sptps_start(&sptps1, fd + 0, true, true, key1, key2, "sptps_speed", 11, send_data, receive_record); sptps_start(&sptps2, fd + 1, false, true, key2, key1, "sptps_speed", 11, send_data, receive_record); while(poll(pfd, 2, 0)) { if(pfd[0].revents) receive_data(&sptps1); if(pfd[1].revents) receive_data(&sptps2); } fprintf(stderr, "SPTPS/UDP transmit for %lg seconds: ", duration); for(clock_start(); clock_countto(duration);) { if(!sptps_send_record(&sptps1, 0, buf1, 1451)) abort(); receive_data(&sptps2); } rate *= 2 * 1451 * 8; if(rate > 1e9) fprintf(stderr, "%14.2lf Gbit/s\n", rate / 1e9); else if(rate > 1e6) fprintf(stderr, "%14.2lf Mbit/s\n", rate / 1e6); else if(rate > 1e3) fprintf(stderr, "%14.2lf kbit/s\n", rate / 1e3); sptps_stop(&sptps1); sptps_stop(&sptps2); // Clean up close(fd[0]); close(fd[1]); ecdsa_free(key1); ecdsa_free(key2); crypto_exit(); return 0; }
// set file offset to beginning before calling int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs::file* f, bool verbose) { u8 header[0xA0] = { 0 }; u8 empty_header[0xA0] = { 0 }; u8 header_hash[0x10] = { 0 }; u8 metadata_hash[0x10] = { 0 }; const u64 file_offset = f->pos(); // Check NPD version and flags. if ((npd->version == 0) || (npd->version == 1)) { if (edat->flags & 0x7EFFFFFE) { LOG_ERROR(LOADER, "EDAT: Bad header flags!"); return 1; } } else if (npd->version == 2) { if (edat->flags & 0x7EFFFFE0) { LOG_ERROR(LOADER, "EDAT: Bad header flags!"); return 1; } } else if ((npd->version == 3) || (npd->version == 4)) { if (edat->flags & 0x7EFFFFC0) { LOG_ERROR(LOADER, "EDAT: Bad header flags!"); return 1; } } else { LOG_ERROR(LOADER, "EDAT: Unknown version!"); return 1; } // Read in the file header. f->read(header, 0xA0); // Read in the header and metadata section hashes. f->seek(file_offset + 0x90); f->read(metadata_hash, 0x10); f->read(header_hash, 0x10); // Setup the hashing mode and the crypto mode used in the file. const int crypto_mode = 0x1; int hash_mode = ((edat->flags & EDAT_ENCRYPTED_KEY_FLAG) == 0) ? 0x00000002 : 0x10000002; if ((edat->flags & EDAT_DEBUG_DATA_FLAG) != 0) { hash_mode |= 0x01000000; if (verbose) LOG_WARNING(LOADER, "EDAT: DEBUG data detected!"); } // Setup header key and iv buffers. unsigned char header_key[0x10] = { 0 }; unsigned char header_iv[0x10] = { 0 }; // Test the header hash (located at offset 0xA0). if (!decrypt(hash_mode, crypto_mode, (npd->version == 4), header, empty_header, 0xA0, header_key, header_iv, key, header_hash)) { if (verbose) LOG_WARNING(LOADER, "EDAT: Header hash is invalid!"); // If the header hash test fails and the data is not DEBUG, then RAP/RIF/KLIC key is invalid. if ((edat->flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG) { LOG_ERROR(LOADER, "EDAT: RAP/RIF/KLIC key is invalid!"); return 1; } } // Parse the metadata info. const int metadata_section_size = ((edat->flags & EDAT_COMPRESSED_FLAG) != 0 || (edat->flags & EDAT_FLAG_0x20) != 0) ? 0x20 : 0x10; if (((edat->flags & EDAT_COMPRESSED_FLAG) != 0)) { if (verbose) LOG_WARNING(LOADER, "EDAT: COMPRESSED data detected!"); } const int block_num = (int)((edat->file_size + edat->block_size - 1) / edat->block_size); const int metadata_offset = 0x100; const int metadata_size = metadata_section_size * block_num; u64 metadata_section_offset = metadata_offset; long bytes_read = 0; long bytes_to_read = metadata_size; std::unique_ptr<u8> metadata(new u8[metadata_size]); std::unique_ptr<u8> empty_metadata(new u8[metadata_size]); while (bytes_to_read > 0) { // Locate the metadata blocks. f->seek(file_offset + metadata_section_offset); // Read in the metadata. f->read(metadata.get() + bytes_read, metadata_section_size); // Adjust sizes. bytes_read += metadata_section_size; bytes_to_read -= metadata_section_size; if (((edat->flags & EDAT_FLAG_0x20) != 0)) // Metadata block before each data block. metadata_section_offset += (metadata_section_size + edat->block_size); else metadata_section_offset += metadata_section_size; } // Test the metadata section hash (located at offset 0x90). if (!decrypt(hash_mode, crypto_mode, (npd->version == 4), metadata.get(), empty_metadata.get(), metadata_size, header_key, header_iv, key, metadata_hash)) { if (verbose) LOG_WARNING(LOADER, "EDAT: Metadata section hash is invalid!"); } // Checking ECDSA signatures. if ((edat->flags & EDAT_DEBUG_DATA_FLAG) == 0) { // Setup buffers. unsigned char metadata_signature[0x28] = { 0 }; unsigned char header_signature[0x28] = { 0 }; unsigned char signature_hash[20] = { 0 }; unsigned char signature_r[0x15] = { 0 }; unsigned char signature_s[0x15] = { 0 }; unsigned char zero_buf[0x15] = { 0 }; // Setup ECDSA curve and public key. ecdsa_set_curve(VSH_CURVE_P, VSH_CURVE_A, VSH_CURVE_B, VSH_CURVE_N, VSH_CURVE_GX, VSH_CURVE_GY); ecdsa_set_pub(VSH_PUB); // Read in the metadata and header signatures. f->seek(file_offset + 0xB0); f->read(metadata_signature, 0x28); f->read(header_signature, 0x28); // Checking metadata signature. // Setup signature r and s. memcpy(signature_r + 01, metadata_signature, 0x14); memcpy(signature_s + 01, metadata_signature + 0x14, 0x14); if ((!memcmp(signature_r, zero_buf, 0x15)) || (!memcmp(signature_s, zero_buf, 0x15))) LOG_WARNING(LOADER, "EDAT: Metadata signature is invalid!"); else { // Setup signature hash. if ((edat->flags & EDAT_FLAG_0x20) != 0) //Sony failed again, they used buffer from 0x100 with half size of real metadata. { int metadata_buf_size = block_num * 0x10; std::unique_ptr<u8> metadata_buf(new u8[metadata_buf_size]); f->seek(file_offset + metadata_offset); f->read(metadata_buf.get(), metadata_buf_size); sha1(metadata_buf.get(), metadata_buf_size, signature_hash); } else sha1(metadata.get(), metadata_size, signature_hash); if (!ecdsa_verify(signature_hash, signature_r, signature_s)) { LOG_WARNING(LOADER, "EDAT: Metadata signature is invalid!"); if (((unsigned long long)edat->block_size * block_num) > 0x100000000) LOG_WARNING(LOADER, "EDAT: *Due to large file size, metadata signature status may be incorrect!"); } } // Checking header signature. // Setup header signature r and s. memset(signature_r, 0, 0x15); memset(signature_s, 0, 0x15); memcpy(signature_r + 01, header_signature, 0x14); memcpy(signature_s + 01, header_signature + 0x14, 0x14); if ((!memcmp(signature_r, zero_buf, 0x15)) || (!memcmp(signature_s, zero_buf, 0x15))) LOG_WARNING(LOADER, "EDAT: Header signature is invalid!"); else { // Setup header signature hash. memset(signature_hash, 0, 20); std::unique_ptr<u8> header_buf(new u8[0xD8]); f->seek(file_offset); f->read(header_buf.get(), 0xD8); sha1(header_buf.get(), 0xD8, signature_hash ); if (!ecdsa_verify(signature_hash, signature_r, signature_s)) LOG_WARNING(LOADER, "EDAT: Header signature is invalid!"); } } return 0; }