|
12 | 12 | #include <string.h> |
13 | 13 |
|
14 | 14 | #include "wolfhsm/wh_client.h" |
| 15 | +#include "wolfhsm/wh_client_crypto.h" |
| 16 | +#include "wolfhsm/wh_common.h" |
15 | 17 | #include "wolfhsm/wh_comm.h" |
16 | 18 | #include "wolfhsm/wh_error.h" |
17 | 19 |
|
| 20 | +#include "wolfssl/wolfcrypt/aes.h" |
18 | 21 | #include "wolfssl/wolfcrypt/random.h" |
| 22 | +#include "wolfssl/wolfcrypt/sha256.h" |
19 | 23 |
|
20 | 24 | #include "wh_transport_nsc.h" |
21 | 25 |
|
@@ -57,9 +61,117 @@ static int wolfhsm_test_rng(void) |
57 | 61 | return 0; |
58 | 62 | } |
59 | 63 |
|
| 64 | +static int wolfhsm_test_sha256(void) |
| 65 | +{ |
| 66 | + /* SHA256("abc") — FIPS 180-2, Appendix B.1. */ |
| 67 | + static const uint8_t expected[WC_SHA256_DIGEST_SIZE] = { |
| 68 | + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, |
| 69 | + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, |
| 70 | + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, |
| 71 | + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad |
| 72 | + }; |
| 73 | + wc_Sha256 sha; |
| 74 | + uint8_t digest[WC_SHA256_DIGEST_SIZE]; |
| 75 | + int rc; |
| 76 | + |
| 77 | + memset(&sha, 0, sizeof(sha)); |
| 78 | + memset(digest, 0, sizeof(digest)); |
| 79 | + |
| 80 | + rc = wc_InitSha256_ex(&sha, NULL, WH_DEV_ID); |
| 81 | + if (rc != 0) { |
| 82 | + printf("wolfHSM SHA256 init failed: %d\r\n", rc); |
| 83 | + return rc; |
| 84 | + } |
| 85 | + |
| 86 | + rc = wc_Sha256Update(&sha, (const uint8_t*)"abc", 3); |
| 87 | + if (rc == 0) { |
| 88 | + rc = wc_Sha256Final(&sha, digest); |
| 89 | + } |
| 90 | + wc_Sha256Free(&sha); |
| 91 | + if (rc != 0) { |
| 92 | + printf("wolfHSM SHA256 hash failed: %d\r\n", rc); |
| 93 | + return rc; |
| 94 | + } |
| 95 | + |
| 96 | + if (memcmp(digest, expected, sizeof(expected)) != 0) { |
| 97 | + printf("wolfHSM SHA256 mismatch\r\n"); |
| 98 | + return -1; |
| 99 | + } |
| 100 | + printf("wolfHSM SHA256 ok\r\n"); |
| 101 | + return 0; |
| 102 | +} |
| 103 | + |
| 104 | +static int wolfhsm_test_aes_cached(whClientContext *client) |
| 105 | +{ |
| 106 | + /* FIPS 197 Appendix B AES-128 vector. CBC with IV=0 yields the same |
| 107 | + * first-block ciphertext as ECB, so a single block under CBC suffices |
| 108 | + * to verify the key+algorithm wired through correctly. */ |
| 109 | + static const uint8_t key[16] = { |
| 110 | + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 111 | + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f |
| 112 | + }; |
| 113 | + static const uint8_t pt[16] = { |
| 114 | + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, |
| 115 | + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff |
| 116 | + }; |
| 117 | + static const uint8_t expected[16] = { |
| 118 | + 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, |
| 119 | + 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a |
| 120 | + }; |
| 121 | + static const uint8_t iv[16] = { 0 }; |
| 122 | + Aes aes; |
| 123 | + uint8_t ct[16]; |
| 124 | + uint16_t keyId = WH_KEYID_ERASED; |
| 125 | + int rc; |
| 126 | + |
| 127 | + memset(&aes, 0, sizeof(aes)); |
| 128 | + memset(ct, 0, sizeof(ct)); |
| 129 | + |
| 130 | + rc = wh_Client_KeyCache(client, WH_NVM_FLAGS_USAGE_ENCRYPT, NULL, 0, |
| 131 | + key, (uint16_t)sizeof(key), &keyId); |
| 132 | + if (rc != WH_ERROR_OK) { |
| 133 | + printf("wolfHSM KeyCache failed: %d\r\n", rc); |
| 134 | + return rc; |
| 135 | + } |
| 136 | + |
| 137 | + rc = wc_AesInit(&aes, NULL, WH_DEV_ID); |
| 138 | + if (rc != 0) { |
| 139 | + printf("wolfHSM AesInit failed: %d\r\n", rc); |
| 140 | + goto out; |
| 141 | + } |
| 142 | + |
| 143 | + rc = wh_Client_AesSetKeyId(&aes, keyId); |
| 144 | + if (rc != WH_ERROR_OK) { |
| 145 | + printf("wolfHSM AesSetKeyId failed: %d\r\n", rc); |
| 146 | + goto out; |
| 147 | + } |
| 148 | + |
| 149 | + rc = wc_AesSetIV(&aes, iv); |
| 150 | + if (rc == 0) { |
| 151 | + rc = wc_AesCbcEncrypt(&aes, ct, pt, (word32)sizeof(pt)); |
| 152 | + } |
| 153 | + if (rc != 0) { |
| 154 | + printf("wolfHSM AES encrypt failed: %d\r\n", rc); |
| 155 | + goto out; |
| 156 | + } |
| 157 | + |
| 158 | + if (memcmp(ct, expected, sizeof(expected)) != 0) { |
| 159 | + printf("wolfHSM AES mismatch\r\n"); |
| 160 | + rc = -1; |
| 161 | + goto out; |
| 162 | + } |
| 163 | + printf("wolfHSM AES ok\r\n"); |
| 164 | + |
| 165 | +out: |
| 166 | + wc_AesFree(&aes); |
| 167 | + (void)wh_Client_KeyEvict(client, keyId); |
| 168 | + return rc; |
| 169 | +} |
| 170 | + |
60 | 171 | /* Initializes the wolfHSM client (auto-registers the wolfCrypt cryptocb |
61 | | - * under WH_DEV_ID), runs the CommInit handshake, exercises one crypto |
62 | | - * round-trip (RNG) through the secure-side server. */ |
| 172 | + * under WH_DEV_ID), runs the CommInit handshake, exercises crypto |
| 173 | + * round-trips (RNG, SHA256, AES with cached key) through the |
| 174 | + * secure-side server. */ |
63 | 175 | int cmd_wolfhsm_test(const char *args) |
64 | 176 | { |
65 | 177 | static const whTransportNscClientConfig nsc_cfg = { 0 }; |
@@ -105,6 +217,18 @@ int cmd_wolfhsm_test(const char *args) |
105 | 217 | return rc; |
106 | 218 | } |
107 | 219 |
|
| 220 | + rc = wolfhsm_test_sha256(); |
| 221 | + if (rc != 0) { |
| 222 | + (void)wh_Client_Cleanup(&client); |
| 223 | + return rc; |
| 224 | + } |
| 225 | + |
| 226 | + rc = wolfhsm_test_aes_cached(&client); |
| 227 | + if (rc != 0) { |
| 228 | + (void)wh_Client_Cleanup(&client); |
| 229 | + return rc; |
| 230 | + } |
| 231 | + |
108 | 232 | printf("wolfHSM NSC tests passed\r\n"); |
109 | 233 |
|
110 | 234 | (void)wh_Client_Cleanup(&client); |
|
0 commit comments