1a8e1175bSopenharmony_ci/* BEGIN_HEADER */ 2a8e1175bSopenharmony_ci#include "lmots.h" 3a8e1175bSopenharmony_ci#include "mbedtls/lms.h" 4a8e1175bSopenharmony_ci 5a8e1175bSopenharmony_ci#if defined(MBEDTLS_TEST_HOOKS) 6a8e1175bSopenharmony_ciint check_lmots_private_key_for_leak(unsigned char *sig) 7a8e1175bSopenharmony_ci{ 8a8e1175bSopenharmony_ci size_t idx; 9a8e1175bSopenharmony_ci 10a8e1175bSopenharmony_ci for (idx = MBEDTLS_LMOTS_SIG_SIGNATURE_OFFSET(MBEDTLS_LMOTS_SHA256_N32_W8); 11a8e1175bSopenharmony_ci idx < MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8); 12a8e1175bSopenharmony_ci idx++) { 13a8e1175bSopenharmony_ci TEST_EQUAL(sig[idx], 0x7E); 14a8e1175bSopenharmony_ci } 15a8e1175bSopenharmony_ci 16a8e1175bSopenharmony_ci return 0; 17a8e1175bSopenharmony_ci 18a8e1175bSopenharmony_ciexit: 19a8e1175bSopenharmony_ci return -1; 20a8e1175bSopenharmony_ci} 21a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_TEST_HOOKS) */ 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci/* END_HEADER */ 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES 26a8e1175bSopenharmony_ci * depends_on:MBEDTLS_LMS_C 27a8e1175bSopenharmony_ci * END_DEPENDENCIES 28a8e1175bSopenharmony_ci */ 29a8e1175bSopenharmony_ci 30a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_LMS_PRIVATE */ 31a8e1175bSopenharmony_civoid lmots_sign_verify_test(data_t *msg, data_t *key_id, int leaf_id, 32a8e1175bSopenharmony_ci data_t *seed) 33a8e1175bSopenharmony_ci{ 34a8e1175bSopenharmony_ci mbedtls_lmots_public_t pub_ctx; 35a8e1175bSopenharmony_ci mbedtls_lmots_private_t priv_ctx; 36a8e1175bSopenharmony_ci unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)]; 37a8e1175bSopenharmony_ci 38a8e1175bSopenharmony_ci mbedtls_lmots_public_init(&pub_ctx); 39a8e1175bSopenharmony_ci mbedtls_lmots_private_init(&priv_ctx); 40a8e1175bSopenharmony_ci 41a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_generate_private_key(&priv_ctx, MBEDTLS_LMOTS_SHA256_N32_W8, 42a8e1175bSopenharmony_ci key_id->x, leaf_id, seed->x, seed->len), 0); 43a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_calculate_public_key(&pub_ctx, &priv_ctx), 0); 44a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_sign(&priv_ctx, &mbedtls_test_rnd_std_rand, NULL, 45a8e1175bSopenharmony_ci msg->x, msg->len, sig, sizeof(sig), NULL), 0); 46a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&pub_ctx, msg->x, msg->len, sig, sizeof(sig)), 0); 47a8e1175bSopenharmony_ci 48a8e1175bSopenharmony_ciexit: 49a8e1175bSopenharmony_ci mbedtls_lmots_public_free(&pub_ctx); 50a8e1175bSopenharmony_ci mbedtls_lmots_private_free(&priv_ctx); 51a8e1175bSopenharmony_ci} 52a8e1175bSopenharmony_ci/* END_CASE */ 53a8e1175bSopenharmony_ci 54a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_LMS_PRIVATE */ 55a8e1175bSopenharmony_civoid lmots_sign_verify_null_msg_test(data_t *key_id, int leaf_id, data_t *seed) 56a8e1175bSopenharmony_ci{ 57a8e1175bSopenharmony_ci mbedtls_lmots_public_t pub_ctx; 58a8e1175bSopenharmony_ci mbedtls_lmots_private_t priv_ctx; 59a8e1175bSopenharmony_ci unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)]; 60a8e1175bSopenharmony_ci 61a8e1175bSopenharmony_ci mbedtls_lmots_public_init(&pub_ctx); 62a8e1175bSopenharmony_ci mbedtls_lmots_private_init(&priv_ctx); 63a8e1175bSopenharmony_ci 64a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_generate_private_key(&priv_ctx, MBEDTLS_LMOTS_SHA256_N32_W8, 65a8e1175bSopenharmony_ci key_id->x, leaf_id, seed->x, seed->len), 0); 66a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_calculate_public_key(&pub_ctx, &priv_ctx), 0); 67a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_sign(&priv_ctx, &mbedtls_test_rnd_std_rand, NULL, 68a8e1175bSopenharmony_ci NULL, 0, sig, sizeof(sig), NULL), 0); 69a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&pub_ctx, NULL, 0, sig, sizeof(sig)), 0); 70a8e1175bSopenharmony_ci 71a8e1175bSopenharmony_ciexit: 72a8e1175bSopenharmony_ci mbedtls_lmots_public_free(&pub_ctx); 73a8e1175bSopenharmony_ci mbedtls_lmots_private_free(&priv_ctx); 74a8e1175bSopenharmony_ci} 75a8e1175bSopenharmony_ci/* END_CASE */ 76a8e1175bSopenharmony_ci 77a8e1175bSopenharmony_ci/* BEGIN_CASE */ 78a8e1175bSopenharmony_civoid lmots_verify_test(data_t *msg, data_t *sig, data_t *pub_key, 79a8e1175bSopenharmony_ci int expected_rc) 80a8e1175bSopenharmony_ci{ 81a8e1175bSopenharmony_ci mbedtls_lmots_public_t ctx; 82a8e1175bSopenharmony_ci unsigned int size; 83a8e1175bSopenharmony_ci unsigned char *tmp_sig = NULL; 84a8e1175bSopenharmony_ci 85a8e1175bSopenharmony_ci mbedtls_lmots_public_init(&ctx); 86a8e1175bSopenharmony_ci 87a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_import_public_key(&ctx, pub_key->x, pub_key->len), 0); 88a8e1175bSopenharmony_ci 89a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&ctx, msg->x, msg->len, sig->x, sig->len), expected_rc); 90a8e1175bSopenharmony_ci 91a8e1175bSopenharmony_ci /* Test negative cases if the input data is valid */ 92a8e1175bSopenharmony_ci if (expected_rc == 0) { 93a8e1175bSopenharmony_ci if (msg->len >= 1) { 94a8e1175bSopenharmony_ci /* Altering first message byte must cause verification failure */ 95a8e1175bSopenharmony_ci msg->x[0] ^= 1; 96a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&ctx, msg->x, msg->len, sig->x, sig->len), 97a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_VERIFY_FAILED); 98a8e1175bSopenharmony_ci msg->x[0] ^= 1; 99a8e1175bSopenharmony_ci 100a8e1175bSopenharmony_ci /* Altering last message byte must cause verification failure */ 101a8e1175bSopenharmony_ci msg->x[msg->len - 1] ^= 1; 102a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&ctx, msg->x, msg->len, sig->x, sig->len), 103a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_VERIFY_FAILED); 104a8e1175bSopenharmony_ci msg->x[msg->len - 1] ^= 1; 105a8e1175bSopenharmony_ci } 106a8e1175bSopenharmony_ci 107a8e1175bSopenharmony_ci /* Altering first signature byte must cause verification failure */ 108a8e1175bSopenharmony_ci sig->x[0] ^= 1; 109a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&ctx, msg->x, msg->len, sig->x, sig->len), 110a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_VERIFY_FAILED); 111a8e1175bSopenharmony_ci sig->x[0] ^= 1; 112a8e1175bSopenharmony_ci 113a8e1175bSopenharmony_ci /* Altering last signature byte must cause verification failure */ 114a8e1175bSopenharmony_ci sig->x[sig->len - 1] ^= 1; 115a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&ctx, msg->x, msg->len, sig->x, sig->len), 116a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_VERIFY_FAILED); 117a8e1175bSopenharmony_ci sig->x[sig->len - 1] ^= 1; 118a8e1175bSopenharmony_ci 119a8e1175bSopenharmony_ci /* Signatures of all sizes must not verify, whether shorter or longer */ 120a8e1175bSopenharmony_ci for (size = 0; size < sig->len; size++) { 121a8e1175bSopenharmony_ci if (size == sig->len) { 122a8e1175bSopenharmony_ci continue; 123a8e1175bSopenharmony_ci } 124a8e1175bSopenharmony_ci 125a8e1175bSopenharmony_ci TEST_CALLOC(tmp_sig, size); 126a8e1175bSopenharmony_ci if (tmp_sig != NULL) { 127a8e1175bSopenharmony_ci memcpy(tmp_sig, sig->x, MIN(size, sig->len)); 128a8e1175bSopenharmony_ci } 129a8e1175bSopenharmony_ci 130a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_verify(&ctx, msg->x, msg->len, tmp_sig, size), 131a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_VERIFY_FAILED); 132a8e1175bSopenharmony_ci mbedtls_free(tmp_sig); 133a8e1175bSopenharmony_ci tmp_sig = NULL; 134a8e1175bSopenharmony_ci } 135a8e1175bSopenharmony_ci } 136a8e1175bSopenharmony_ci 137a8e1175bSopenharmony_ciexit: 138a8e1175bSopenharmony_ci mbedtls_free(tmp_sig); 139a8e1175bSopenharmony_ci mbedtls_lmots_public_free(&ctx); 140a8e1175bSopenharmony_ci} 141a8e1175bSopenharmony_ci/* END_CASE */ 142a8e1175bSopenharmony_ci 143a8e1175bSopenharmony_ci/* BEGIN_CASE */ 144a8e1175bSopenharmony_civoid lmots_import_export_test(data_t *pub_key, int expected_import_rc) 145a8e1175bSopenharmony_ci{ 146a8e1175bSopenharmony_ci mbedtls_lmots_public_t ctx; 147a8e1175bSopenharmony_ci unsigned char *exported_pub_key = NULL; 148a8e1175bSopenharmony_ci size_t exported_pub_key_buf_size; 149a8e1175bSopenharmony_ci size_t exported_pub_key_size; 150a8e1175bSopenharmony_ci 151a8e1175bSopenharmony_ci mbedtls_lmots_public_init(&ctx); 152a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_import_public_key(&ctx, pub_key->x, pub_key->len), 153a8e1175bSopenharmony_ci expected_import_rc); 154a8e1175bSopenharmony_ci 155a8e1175bSopenharmony_ci if (expected_import_rc == 0) { 156a8e1175bSopenharmony_ci exported_pub_key_buf_size = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8); 157a8e1175bSopenharmony_ci TEST_CALLOC(exported_pub_key, exported_pub_key_buf_size); 158a8e1175bSopenharmony_ci 159a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_export_public_key(&ctx, exported_pub_key, 160a8e1175bSopenharmony_ci exported_pub_key_buf_size, 161a8e1175bSopenharmony_ci &exported_pub_key_size), 0); 162a8e1175bSopenharmony_ci 163a8e1175bSopenharmony_ci TEST_EQUAL(exported_pub_key_size, 164a8e1175bSopenharmony_ci MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)); 165a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(pub_key->x, pub_key->len, 166a8e1175bSopenharmony_ci exported_pub_key, exported_pub_key_size); 167a8e1175bSopenharmony_ci mbedtls_free(exported_pub_key); 168a8e1175bSopenharmony_ci exported_pub_key = NULL; 169a8e1175bSopenharmony_ci 170a8e1175bSopenharmony_ci /* Export into too-small buffer should fail */ 171a8e1175bSopenharmony_ci exported_pub_key_buf_size = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8) - 1; 172a8e1175bSopenharmony_ci TEST_CALLOC(exported_pub_key, exported_pub_key_buf_size); 173a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_export_public_key(&ctx, exported_pub_key, 174a8e1175bSopenharmony_ci exported_pub_key_buf_size, NULL), 175a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_BUFFER_TOO_SMALL); 176a8e1175bSopenharmony_ci mbedtls_free(exported_pub_key); 177a8e1175bSopenharmony_ci exported_pub_key = NULL; 178a8e1175bSopenharmony_ci 179a8e1175bSopenharmony_ci /* Export into too-large buffer should succeed */ 180a8e1175bSopenharmony_ci exported_pub_key_buf_size = MBEDTLS_LMOTS_PUBLIC_KEY_LEN(MBEDTLS_LMOTS_SHA256_N32_W8) + 1; 181a8e1175bSopenharmony_ci TEST_CALLOC(exported_pub_key, exported_pub_key_buf_size); 182a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_export_public_key(&ctx, exported_pub_key, 183a8e1175bSopenharmony_ci exported_pub_key_buf_size, 184a8e1175bSopenharmony_ci &exported_pub_key_size), 185a8e1175bSopenharmony_ci 0); 186a8e1175bSopenharmony_ci TEST_MEMORY_COMPARE(pub_key->x, pub_key->len, 187a8e1175bSopenharmony_ci exported_pub_key, exported_pub_key_size); 188a8e1175bSopenharmony_ci mbedtls_free(exported_pub_key); 189a8e1175bSopenharmony_ci exported_pub_key = NULL; 190a8e1175bSopenharmony_ci } 191a8e1175bSopenharmony_ci 192a8e1175bSopenharmony_ciexit: 193a8e1175bSopenharmony_ci mbedtls_lmots_public_free(&ctx); 194a8e1175bSopenharmony_ci mbedtls_free(exported_pub_key); 195a8e1175bSopenharmony_ci} 196a8e1175bSopenharmony_ci/* END_CASE */ 197a8e1175bSopenharmony_ci 198a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_LMS_PRIVATE */ 199a8e1175bSopenharmony_civoid lmots_reuse_test(data_t *msg, data_t *key_id, int leaf_id, data_t *seed) 200a8e1175bSopenharmony_ci{ 201a8e1175bSopenharmony_ci mbedtls_lmots_private_t ctx; 202a8e1175bSopenharmony_ci unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)]; 203a8e1175bSopenharmony_ci 204a8e1175bSopenharmony_ci mbedtls_lmots_private_init(&ctx); 205a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_generate_private_key(&ctx, MBEDTLS_LMOTS_SHA256_N32_W8, 206a8e1175bSopenharmony_ci key_id->x, leaf_id, seed->x, 207a8e1175bSopenharmony_ci seed->len), 0); 208a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_sign(&ctx, mbedtls_test_rnd_std_rand, NULL, 209a8e1175bSopenharmony_ci msg->x, msg->len, sig, sizeof(sig), NULL), 0); 210a8e1175bSopenharmony_ci 211a8e1175bSopenharmony_ci /* Running another sign operation should fail, since the key should now have 212a8e1175bSopenharmony_ci * been erased. 213a8e1175bSopenharmony_ci */ 214a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_sign(&ctx, mbedtls_test_rnd_std_rand, NULL, 215a8e1175bSopenharmony_ci msg->x, msg->len, sig, sizeof(sig), NULL), 216a8e1175bSopenharmony_ci MBEDTLS_ERR_LMS_BAD_INPUT_DATA); 217a8e1175bSopenharmony_ci 218a8e1175bSopenharmony_ciexit: 219a8e1175bSopenharmony_ci mbedtls_lmots_private_free(&ctx); 220a8e1175bSopenharmony_ci} 221a8e1175bSopenharmony_ci/* END_CASE */ 222a8e1175bSopenharmony_ci 223a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_LMS_PRIVATE */ 224a8e1175bSopenharmony_civoid lmots_signature_leak_test(data_t *msg, data_t *key_id, int leaf_id, 225a8e1175bSopenharmony_ci data_t *seed) 226a8e1175bSopenharmony_ci{ 227a8e1175bSopenharmony_ci mbedtls_lmots_private_t ctx; 228a8e1175bSopenharmony_ci unsigned char sig[MBEDTLS_LMOTS_SIG_LEN(MBEDTLS_LMOTS_SHA256_N32_W8)]; 229a8e1175bSopenharmony_ci 230a8e1175bSopenharmony_ci mbedtls_lmots_sign_private_key_invalidated_hook = &check_lmots_private_key_for_leak; 231a8e1175bSopenharmony_ci 232a8e1175bSopenharmony_ci /* Fill with recognisable pattern */ 233a8e1175bSopenharmony_ci memset(sig, 0x7E, sizeof(sig)); 234a8e1175bSopenharmony_ci 235a8e1175bSopenharmony_ci mbedtls_lmots_private_init(&ctx); 236a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_generate_private_key(&ctx, MBEDTLS_LMOTS_SHA256_N32_W8, 237a8e1175bSopenharmony_ci key_id->x, leaf_id, seed->x, 238a8e1175bSopenharmony_ci seed->len), 0); 239a8e1175bSopenharmony_ci TEST_EQUAL(mbedtls_lmots_sign(&ctx, mbedtls_test_rnd_std_rand, NULL, 240a8e1175bSopenharmony_ci msg->x, msg->len, sig, sizeof(sig), NULL), 0); 241a8e1175bSopenharmony_ci 242a8e1175bSopenharmony_ciexit: 243a8e1175bSopenharmony_ci mbedtls_lmots_private_free(&ctx); 244a8e1175bSopenharmony_ci mbedtls_lmots_sign_private_key_invalidated_hook = NULL; 245a8e1175bSopenharmony_ci} 246a8e1175bSopenharmony_ci/* END_CASE */ 247