Skip to content

Commit

Permalink
Improve key length validation
Browse files Browse the repository at this point in the history
* Update tr31_key_init() to validate exact TDES and AES key lengths
* Update tr31_export() to return TR31_ERROR_INVALID_KEY_LENGTH if key
  value is not populated and return TR31_ERROR_UNSUPPORTED_KBPK_LENGTH
  if KBPK value is not populated
* Update tr31-tool to ensure that --kbpk is present when --export is
  specified
  • Loading branch information
leonlynch committed Dec 3, 2024
1 parent fcfb027 commit e02d832
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/tr31-tool.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file tr31-tool.c
*
* Copyright 2020-2023 Leon Lynch
* Copyright 2020-2024 Leon Lynch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -593,6 +593,9 @@ static error_t argp_parser_helper(int key, char* arg, struct argp_state* state)
}

// check for required --export options
if (options->export && !options->kbpk) {
argp_error(state, "The --export option requires --kbpk");
}
if (options->export &&
(!options->export_key_algorithm || !options->export_format_version || !options->export_template) &&
!options->export_header
Expand Down
16 changes: 12 additions & 4 deletions src/tr31.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @file tr31.c
* @brief High level TR-31 library interface
*
* Copyright 2020-2023 Leon Lynch
* Copyright 2020-2024 Leon Lynch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -390,14 +390,19 @@ int tr31_key_init(
// validate key length by algorithm
switch (algorithm) {
case TR31_KEY_ALGORITHM_TDES:
if (length > 24) {
if (length != TDES2_KEY_SIZE &&
length != TDES3_KEY_SIZE
) {
// invalid TDES key length
return TR31_ERROR_INVALID_KEY_LENGTH;
}
break;

case TR31_KEY_ALGORITHM_AES:
if (length > 32) {
if (length != AES128_KEY_SIZE &&
length != AES192_KEY_SIZE &&
length != AES256_KEY_SIZE
) {
// invalid AES key length
return TR31_ERROR_INVALID_KEY_LENGTH;
}
Expand Down Expand Up @@ -2330,7 +2335,10 @@ int tr31_export(
return -1;
}
if (!ctx->key.data || !ctx->key.length) {
return -2;
return TR31_ERROR_INVALID_KEY_LENGTH;
}
if (!kbpk->data || !kbpk->length) {
return TR31_ERROR_UNSUPPORTED_KBPK_LENGTH;
}

// validate minimum length (+1 for null-termination)
Expand Down
86 changes: 85 additions & 1 deletion test/tr31_export_test.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file tr31_export_test.c
*
* Copyright 2021-2023 Leon Lynch
* Copyright 2021-2024 Leon Lynch
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand Down Expand Up @@ -812,6 +812,90 @@ int main(void)
struct tr31_ctx_t test_tr31;
char key_block[4096];

// Test error for missing key or KBPK data
{
struct tr31_key_t kbpk;
struct tr31_key_t key;

// Prepare KBPK object
r = tr31_key_init(
TR31_KEY_USAGE_TR31_KBPK,
TR31_KEY_ALGORITHM_TDES,
TR31_KEY_MODE_OF_USE_ENC_DEC,
"00",
TR31_KEY_EXPORT_NONE,
TR31_KEY_CONTEXT_STORAGE,
NULL,
0,
&kbpk
);
if (r) {
fprintf(stderr, "tr31_key_init() error %d: %s\n", r, tr31_get_error_string(r));
return 1;
}

// Prepare key object
r = tr31_key_init(
TR31_KEY_USAGE_PEK,
TR31_KEY_ALGORITHM_TDES,
TR31_KEY_MODE_OF_USE_ENC_DEC,
"00",
TR31_KEY_EXPORT_NONE,
TR31_KEY_CONTEXT_STORAGE,
NULL,
0,
&key
);
if (r) {
fprintf(stderr, "tr31_key_init() error %d: %s\n", r, tr31_get_error_string(r));
return 1;
}

// Prepare TR-31 context
r = tr31_init(TR31_VERSION_B, &key, &test_tr31);
if (r) {
fprintf(stderr, "tr31_init() error %d: %s\n", r, tr31_get_error_string(r));
goto exit;
}

// Attempt key block export with invalid key
r = tr31_export(&test_tr31, &kbpk, 0, key_block, sizeof(key_block));
if (!r) {
fprintf(stderr, "Unexpected tr31_export() success when KBPK is invalid\n");
goto exit;
}
if (r != TR31_ERROR_INVALID_KEY_LENGTH) {
fprintf(stderr, "tr31_export() error %d: %s\n", r, tr31_get_error_string(r));
goto exit;
}

// Populate key data
r = tr31_key_set_data(
&test_tr31.key,
test[0].key_data,
test[0].key_len
);
if (r) {
fprintf(stderr, "tr31_key_set_data() error %d: %s\n", r, tr31_get_error_string(r));
return 1;
}

// Attempt key block export with invalid KBPK
r = tr31_export(&test_tr31, &kbpk, 0, key_block, sizeof(key_block));
if (!r) {
fprintf(stderr, "Unexpected tr31_export() success when KBPK is invalid\n");
goto exit;
}
if (r != TR31_ERROR_UNSUPPORTED_KBPK_LENGTH) {
fprintf(stderr, "tr31_export() error %d: %s\n", r, tr31_get_error_string(r));
goto exit;
}

tr31_release(&test_tr31);
tr31_key_release(&key);
tr31_key_release(&kbpk);
}

for (size_t i = 0; i < sizeof(test) / sizeof(test[0]); ++i) {
printf("Test %zu (%s)...\n", i + 1, test[i].name);

Expand Down

0 comments on commit e02d832

Please sign in to comment.