diff --git a/src/tr31-tool.c b/src/tr31-tool.c index d40b2a7..865bc9d 100644 --- a/src/tr31-tool.c +++ b/src/tr31-tool.c @@ -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 @@ -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 diff --git a/src/tr31.c b/src/tr31.c index 9490e31..c12ac51 100644 --- a/src/tr31.c +++ b/src/tr31.c @@ -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 @@ -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; } @@ -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) diff --git a/test/tr31_export_test.c b/test/tr31_export_test.c index 31715d4..1349347 100644 --- a/test/tr31_export_test.c +++ b/test/tr31_export_test.c @@ -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 @@ -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);