Finish decryption algorithm implementation

This commit is contained in:
Grayson Martin 2023-07-08 12:35:59 -05:00
parent 945f03e646
commit b30f8ae37f
No known key found for this signature in database
GPG key ID: 4914C62F2696A273
3 changed files with 82 additions and 12 deletions

View file

@ -11,6 +11,7 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
../../common/mbedtls/ecp.c
../../common/mbedtls/ecdh.c
../../common/mbedtls/ecc_point_compression.c
../../common/mbedtls/gcm.c
../../common/mbedtls/ecp_curves.c
../../common/mbedtls/certs.c
../../common/mbedtls/camellia.c

View file

@ -39,6 +39,7 @@
#include "mbedtls/bignum.h"
#include "mbedtls/ecdh.h"
#include "mbedtls/ecc_point_compression.h"
#include "mbedtls/gcm.h"
uint8_t ecpData[] = { 0x6a, 0x01, 0x00, 0x00, 0x04 };
uint8_t aid[] = { 0x4f, 0x53, 0x45, 0x2e, 0x56, 0x41, 0x53, 0x2e, 0x30, 0x31 };
@ -232,7 +233,35 @@ static int LoadMobileEphemeralKey(uint8_t *xcoordBuf, mbedtls_ecp_keypair *pubKe
return PM3_SUCCESS;
}
static int DecryptVASCryptogram(uint8_t *cryptogram, size_t cryptogramLen, mbedtls_ecp_keypair *privKey, uint8_t *out, size_t *outLen, uint8_t *timestamp) {
static int internalVasDecrypt(uint8_t *cipherText, size_t cipherTextLen, uint8_t *sharedSecret, uint8_t *ansiSharedInfo, size_t ansiSharedInfoLen, uint8_t *gcmAad, size_t gcmAadLen, uint8_t *out, size_t *outLen) {
uint8_t key[32] = {0};
if (ansi_x963_sha256(sharedSecret, 32, ansiSharedInfo, ansiSharedInfoLen, sizeof(key), key)) {
PrintAndLogEx(FAILED, "ANSI X9.63 key derivation failed");
return PM3_EINVARG;
}
uint8_t iv[16] = {0};
mbedtls_gcm_context gcmCtx;
mbedtls_gcm_init(&gcmCtx);
if (mbedtls_gcm_setkey(&gcmCtx, MBEDTLS_CIPHER_ID_AES, key, sizeof(key) * 8)) {
PrintAndLogEx(FAILED, "Unable to use key in GCM context");
return PM3_EINVARG;
}
if (mbedtls_gcm_auth_decrypt(&gcmCtx, cipherTextLen - 16, iv, sizeof(iv), gcmAad, gcmAadLen, cipherText + cipherTextLen - 16, 16, cipherText, out)) {
PrintAndLogEx(FAILED, "Failed to perform GCM decryption");
return PM3_EINVARG;
}
mbedtls_gcm_free(&gcmCtx);
*outLen = cipherTextLen - 16;
return PM3_SUCCESS;
}
static int DecryptVASCryptogram(uint8_t *pidHash, uint8_t *cryptogram, size_t cryptogramLen, mbedtls_ecp_keypair *privKey, uint8_t *out, size_t *outLen, uint32_t *timestamp) {
uint8_t keyHint[4] = {0};
if (GetPrivateKeyHint(privKey, keyHint) != PM3_SUCCESS) {
PrintAndLogEx(FAILED, "Unable to generate key hint");
@ -263,9 +292,42 @@ static int DecryptVASCryptogram(uint8_t *cryptogram, size_t cryptogramLen, mbedt
PrintAndLogEx(FAILED, "Failed to generate ECDH shared secret");
return PM3_EINVARG;
}
mbedtls_mpi_free(&sharedSecret);
mbedtls_ecp_keypair_free(&mobilePubKey);
uint8_t sharedSecretBytes[32] = {0};
if (mbedtls_mpi_write_binary(&sharedSecret, sharedSecretBytes, sizeof(sharedSecretBytes))) {
mbedtls_mpi_free(&sharedSecret);
PrintAndLogEx(FAILED, "Failed to generate ECDH shared secret");
return PM3_EINVARG;
}
mbedtls_mpi_free(&sharedSecret);
uint8_t string1[27] = "ApplePay encrypted VAS data";
uint8_t string2[13] = "id-aes256-GCM";
uint8_t method1SharedInfo[73] = {0};
method1SharedInfo[0] = 13;
memcpy(method1SharedInfo + 1, string2, sizeof(string2));
memcpy(method1SharedInfo + 1 + sizeof(string2), string1, sizeof(string1));
memcpy(method1SharedInfo + 1 + sizeof(string2) + sizeof(string1), pidHash, 32);
uint8_t decryptedData[68] = {0};
size_t decryptedDataLen = 0;
if (internalVasDecrypt(cryptogram + 4 + 32, cryptogramLen - 4 - 32, sharedSecretBytes, method1SharedInfo, sizeof(method1SharedInfo), NULL, 0, decryptedData, &decryptedDataLen)) {
if (internalVasDecrypt(cryptogram + 4 + 32, cryptogramLen - 4 - 32, sharedSecretBytes, string1, sizeof(string1), pidHash, 32, decryptedData, &decryptedDataLen)) {
return PM3_EINVARG;
}
}
memcpy(out, decryptedData + 4, decryptedDataLen - 4);
*outLen = decryptedDataLen - 4;
*timestamp = 0;
for (int i = 0; i < 4; ++i) {
*timestamp = (*timestamp << 8) | decryptedData[i];
}
*timestamp = *timestamp + 978328800; // Unix offset for Jan 1, 2001
return PM3_SUCCESS;
}
@ -383,11 +445,12 @@ static int CmdVASReader(const char *Cmd) {
uint8_t cryptogram[120] = {0};
size_t cryptogramLen = 0;
int s = VASReader(passTypeIdLen > 0 ? pidHash : NULL, url, urlLen, cryptogram, &cryptogramLen, verbose);
if (s != PM3_SUCCESS) {
PrintAndLogEx(INFO, "Requesting pass type id: %s", sprint_ascii((uint8_t *) passTypeIdArg->sval[0], passTypeIdLen));
if (VASReader(passTypeIdLen > 0 ? pidHash : NULL, url, urlLen, cryptogram, &cryptogramLen, verbose) != PM3_SUCCESS) {
CLIParserFree(ctx);
mbedtls_ecp_keypair_free(&privKey);
return s;
return PM3_EINVARG;
}
if (verbose) {
@ -396,17 +459,20 @@ static int CmdVASReader(const char *Cmd) {
uint8_t message[64] = {0};
size_t messageLen = 0;
uint8_t timestamp[4] = {0};
uint32_t timestamp = 0;
if (DecryptVASCryptogram(cryptogram, cryptogramLen, &privKey, message, &messageLen, timestamp) != PM3_SUCCESS) {
if (DecryptVASCryptogram(pidHash, cryptogram, cryptogramLen, &privKey, message, &messageLen, &timestamp) != PM3_SUCCESS) {
CLIParserFree(ctx);
mbedtls_ecp_keypair_free(&privKey);
return PM3_EINVARG;
}
PrintAndLogEx(SUCCESS, "Message: %s", sprint_ascii(message, messageLen));
PrintAndLogEx(SUCCESS, "Timestamp: %d", timestamp);
CLIParserFree(ctx);
mbedtls_ecp_keypair_free(&privKey);
return s;
return PM3_SUCCESS;
}
static int CmdVASDecrypt(const char *Cmd) {
@ -459,14 +525,17 @@ static int CmdVASDecrypt(const char *Cmd) {
uint8_t message[64] = {0};
size_t messageLen = 0;
uint8_t timestamp[4] = {0};
uint32_t timestamp = 0;
if (DecryptVASCryptogram(cryptogram, cryptogramLen, &privKey, message, &messageLen, timestamp) != PM3_SUCCESS) {
if (DecryptVASCryptogram(pidHash, cryptogram, cryptogramLen, &privKey, message, &messageLen, &timestamp) != PM3_SUCCESS) {
CLIParserFree(ctx);
mbedtls_ecp_keypair_free(&privKey);
return PM3_EINVARG;
}
PrintAndLogEx(SUCCESS, "Message: %s", sprint_ascii(message, messageLen));
PrintAndLogEx(SUCCESS, "Timestamp: %d", timestamp);
CLIParserFree(ctx);
mbedtls_ecp_keypair_free(&privKey);
return PM3_SUCCESS;

View file

@ -2811,7 +2811,7 @@
* This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
* requisites are enabled as well.
*/
//#define MBEDTLS_GCM_C
#define MBEDTLS_GCM_C
/**
* \def MBEDTLS_HAVEGE_C