|
| 1 | +/* |
| 2 | + * Copyright (C) 2022 Southern Storm Software, Pty Ltd. |
| 3 | + * |
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | + * copy of this software and associated documentation files (the "Software"), |
| 6 | + * to deal in the Software without restriction, including without limitation |
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the |
| 9 | + * Software is furnished to do so, subject to the following conditions: |
| 10 | + * |
| 11 | + * The above copyright notice and this permission notice shall be included |
| 12 | + * in all copies or substantial portions of the Software. |
| 13 | + * |
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| 15 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 17 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| 20 | + * DEALINGS IN THE SOFTWARE. |
| 21 | + */ |
| 22 | + |
| 23 | +/* |
| 24 | +This example runs tests on the HKDF implementation to verify correct behaviour. |
| 25 | +*/ |
| 26 | + |
| 27 | +#include <Crypto.h> |
| 28 | +#include <SHA256.h> |
| 29 | +#include <HKDF.h> |
| 30 | +#include <string.h> |
| 31 | + |
| 32 | +typedef struct |
| 33 | +{ |
| 34 | + const char *name; |
| 35 | + const unsigned char *key; |
| 36 | + size_t key_len; |
| 37 | + const unsigned char *salt; |
| 38 | + size_t salt_len; |
| 39 | + const unsigned char *info; |
| 40 | + size_t info_len; |
| 41 | + const unsigned char *out; |
| 42 | + size_t out_len; |
| 43 | + |
| 44 | +} TestHKDFVector; |
| 45 | + |
| 46 | +/* Test cases from RFC-5869 */ |
| 47 | +static unsigned char const key_1[] = { |
| 48 | + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, |
| 49 | + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, |
| 50 | + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b |
| 51 | +}; |
| 52 | +static unsigned char const salt_1[] = { |
| 53 | + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 54 | + 0x08, 0x09, 0x0a, 0x0b, 0x0c |
| 55 | +}; |
| 56 | +static unsigned char const info_1[] = { |
| 57 | + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, |
| 58 | + 0xf8, 0xf9 |
| 59 | +}; |
| 60 | +static unsigned char const out_1[] = { |
| 61 | + 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, |
| 62 | + 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, |
| 63 | + 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, |
| 64 | + 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, |
| 65 | + 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, |
| 66 | + 0x58, 0x65 |
| 67 | +}; |
| 68 | +static TestHKDFVector const testVectorHKDF_1 = { |
| 69 | + "Test Vector 1", |
| 70 | + key_1, |
| 71 | + 22, |
| 72 | + salt_1, |
| 73 | + 13, |
| 74 | + info_1, |
| 75 | + 10, |
| 76 | + out_1, |
| 77 | + 42 |
| 78 | +}; |
| 79 | + |
| 80 | +HKDF<SHA256> hkdf_context; |
| 81 | + |
| 82 | +uint8_t buffer[128]; |
| 83 | + |
| 84 | +bool testHKDF_N(HKDFCommon *hkdf, const TestHKDFVector *test, size_t inc) |
| 85 | +{ |
| 86 | + size_t size = test->out_len; |
| 87 | + size_t posn, len; |
| 88 | + |
| 89 | + hkdf->setKey(test->key, test->key_len, test->salt, test->salt_len); |
| 90 | + for (posn = 0; posn < size; posn += inc) { |
| 91 | + len = size - posn; |
| 92 | + if (len > inc) |
| 93 | + len = inc; |
| 94 | + hkdf->extract(buffer + posn, len, test->info, test->info_len); |
| 95 | + } |
| 96 | + if (memcmp(buffer, test->out, test->out_len) != 0) |
| 97 | + return false; |
| 98 | + |
| 99 | + return true; |
| 100 | +} |
| 101 | + |
| 102 | +void testHKDF(HKDFCommon *hkdf, const TestHKDFVector *test) |
| 103 | +{ |
| 104 | + bool ok; |
| 105 | + |
| 106 | + Serial.print(test->name); |
| 107 | + Serial.print(" ... "); |
| 108 | + |
| 109 | + ok = testHKDF_N(hkdf, test, test->out_len); |
| 110 | + ok &= testHKDF_N(hkdf, test, 1); |
| 111 | + ok &= testHKDF_N(hkdf, test, 2); |
| 112 | + ok &= testHKDF_N(hkdf, test, 5); |
| 113 | + ok &= testHKDF_N(hkdf, test, 8); |
| 114 | + ok &= testHKDF_N(hkdf, test, 13); |
| 115 | + ok &= testHKDF_N(hkdf, test, 16); |
| 116 | + ok &= testHKDF_N(hkdf, test, 24); |
| 117 | + ok &= testHKDF_N(hkdf, test, 63); |
| 118 | + ok &= testHKDF_N(hkdf, test, 64); |
| 119 | + |
| 120 | + if (ok) |
| 121 | + Serial.println("Passed"); |
| 122 | + else |
| 123 | + Serial.println("Failed"); |
| 124 | +} |
| 125 | + |
| 126 | +void setup() |
| 127 | +{ |
| 128 | + Serial.begin(9600); |
| 129 | + |
| 130 | + Serial.println(); |
| 131 | + |
| 132 | + Serial.print("State Size ... "); |
| 133 | + Serial.println(sizeof(HKDF<SHA256>)); |
| 134 | + Serial.print("Size Without Hash State ... "); |
| 135 | + Serial.println(sizeof(HKDF<SHA256>) - sizeof(SHA256)); |
| 136 | + Serial.println(); |
| 137 | + |
| 138 | + Serial.println("Test Vectors:"); |
| 139 | + testHKDF(&hkdf_context, &testVectorHKDF_1); |
| 140 | + Serial.println(); |
| 141 | +} |
| 142 | + |
| 143 | +void loop() |
| 144 | +{ |
| 145 | +} |
0 commit comments