Skip to content

Commit

Permalink
Use new TDES KCV and AES KCV abstractions
Browse files Browse the repository at this point in the history
  • Loading branch information
leonlynch committed Apr 15, 2022
1 parent 511767c commit 77c3dcc
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 96 deletions.
8 changes: 5 additions & 3 deletions src/tr31.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,18 +423,20 @@ int tr31_key_set_data(struct tr31_key_t* key, const void* data, size_t length)
memset(&key->kcv, 0, sizeof(key->kcv));
if (key->algorithm == TR31_KEY_ALGORITHM_TDES) {
// use legacy KCV for TDES key
// see ANSI X9.24-1:2017, 7.7.2
key->kcv_algorithm = TR31_OPT_BLOCK_KCV_LEGACY;
r = tr31_tdes_kcv(key->data, key->length, key->kcv);
r = crypto_tdes_kcv_legacy(key->data, key->length, key->kcv);
if (r) {
// return error value as-is
return r;
}
key->kcv_len = TDES_KCV_SIZE;
key->kcv_len = DES_KCV_SIZE_LEGACY;

} else if (key->algorithm == TR31_KEY_ALGORITHM_AES) {
// use CMAC-based KCV for AES key
// see ANSI X9.24-1:2017, 7.7.2
key->kcv_algorithm = TR31_OPT_BLOCK_KCV_CMAC;
r = tr31_aes_kcv(key->data, key->length, key->kcv);
r = crypto_aes_kcv(key->data, key->length, key->kcv);
if (r) {
// return error value as-is
return r;
Expand Down
73 changes: 0 additions & 73 deletions src/tr31_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,40 +190,6 @@ int tr31_tdes_kbpk_derive(const void* kbpk, size_t kbpk_len, void* kbek, void* k
return 0;
}

int tr31_tdes_kcv(const void* key, size_t key_len, void* kcv)
{
int r;
uint8_t zero[DES_BLOCK_SIZE];
uint8_t ciphertext[DES_BLOCK_SIZE];

if (!key || !kcv) {
return -1;
}
if (key_len != TDES2_KEY_SIZE && key_len != TDES3_KEY_SIZE) {
return -2;
}

// see ANSI X9.24-1:2017, A.2 Legacy Approach

// zero KCV in case of error
memset(kcv, 0, TDES_KCV_SIZE);

// encrypt zero block with input key
memset(zero, 0, sizeof(zero));
r = crypto_tdes_encrypt_ecb(key, key_len, zero, ciphertext);
if (r) {
// internal error
return r;
}

// KCV is always first 3 bytes of ciphertext
memcpy(kcv, ciphertext, TDES_KCV_SIZE);

crypto_cleanse(ciphertext, sizeof(ciphertext));

return 0;
}

int tr31_aes_verify_cmac(
const void* key,
size_t key_len,
Expand Down Expand Up @@ -366,42 +332,3 @@ int tr31_aes_kbpk_derive(const void* kbpk, size_t kbpk_len, void* kbek, void* kb

return 0;
}

int tr31_aes_kcv(const void* key, size_t key_len, void* kcv)
{
int r;
uint8_t input[AES_BLOCK_SIZE];
uint8_t ciphertext[AES_BLOCK_SIZE];

if (!key || !kcv) {
return -1;
}
if (key_len != AES128_KEY_SIZE &&
key_len != AES192_KEY_SIZE &&
key_len != AES256_KEY_SIZE
) {
return -2;
}

// see ANSI X9.24-1:2017, A.3 CMAC-based Check values

// zero KCV in case of error
memset(kcv, 0, AES_KCV_SIZE);

// use input block populated with 0x00
memset(input, 0x00, sizeof(input));

// Compute CMAC of input block using input key
r = crypto_aes_cmac(key, key_len, input, sizeof(input), ciphertext);
if (r) {
// internal error
return r;
}

// KCV is always first 5 bytes of ciphertext
memcpy(kcv, ciphertext, AES_KCV_SIZE);

crypto_cleanse(ciphertext, sizeof(ciphertext));

return 0;
}
20 changes: 0 additions & 20 deletions src/tr31_crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,12 @@ __BEGIN_DECLS
#define TDES2_KEY_SIZE (DES_KEY_SIZE * 2) ///< Double length triple DES key size in bytes
#define TDES3_KEY_SIZE (DES_KEY_SIZE * 3) ///< Triple length triple DES key size in bytes
#define DES_CIPHERTEXT_LENGTH(plen) (((plen) + DES_BLOCK_SIZE-1) & ~(DES_BLOCK_SIZE-1)) ///< DES ciphertext length at next block boundary
#define TDES_KCV_SIZE (3) ///< Legacy KCV size in bytes

#define AES_BLOCK_SIZE (16) ///< AES block size in bytes
#define AES128_KEY_SIZE (16) ///< AES-128 key size in bytes
#define AES192_KEY_SIZE (24) ///< AES-192 key size in bytes
#define AES256_KEY_SIZE (32) ///< AES-256 key size in bytes
#define AES_CIPHERTEXT_LENGTH(plen) (((plen) + AES_BLOCK_SIZE-1) & ~(AES_BLOCK_SIZE-1)) ///< AES ciphertext length at next block boundary
#define AES_KCV_SIZE (5) ///< CMAC-base KCV size in bytes

#define TR31_DES_KEY_UNDER_DES_LENGTH DES_CIPHERTEXT_LENGTH(2 + DES_KEY_SIZE) ///< 2-byte length + DES key + DES padding, in bytes
#define TR31_DES_KEY_UNDER_AES_LENGTH AES_CIPHERTEXT_LENGTH(2 + DES_KEY_SIZE) ///< 2-byte length + DES key + AES padding, in bytes
Expand Down Expand Up @@ -118,15 +116,6 @@ int tr31_tdes_kbpk_variant(const void* kbpk, size_t kbpk_len, void* kbek, void*
*/
int tr31_tdes_kbpk_derive(const void* kbpk, size_t kbpk_len, void* kbek, void* kbak);

/**
* Compute TDES Key Check Value (KCV)
* @param key Key
* @param key_len Length of key in bytes
* @param kcv Key Check Value output of length @ref TDES_KCV_SIZE
* @return Zero for success. Less than zero for internal error.
*/
int tr31_tdes_kcv(const void* key, size_t key_len, void* kcv);

/**
* Verify using AES CMAC
*
Expand Down Expand Up @@ -160,15 +149,6 @@ int tr31_aes_verify_cmac(
*/
int tr31_aes_kbpk_derive(const void* kbpk, size_t kbpk_len, void* kbek, void* kbak);

/**
* Compute AES Key Check Value (KCV)
* @param key Key
* @param key_len Length of key in bytes
* @param kcv Key Check Value output of length @ref AES_KCV_SIZE
* @return Zero for success. Less than zero for internal error.
*/
int tr31_aes_kcv(const void* key, size_t key_len, void* kcv);

__END_DECLS

#endif

0 comments on commit 77c3dcc

Please sign in to comment.