unit_sha256.c (32078B)
1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */ 2 3 /* 4 This file is part of GNU libmicrohttpd. 5 Copyright (C) 2025 Christian Grothoff 6 7 GNU libmicrohttpd is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public 9 License as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. 11 12 GNU libmicrohttpd is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Lesser General Public License for more details. 16 17 Alternatively, you can redistribute GNU libmicrohttpd and/or 18 modify it under the terms of the GNU General Public License as 19 published by the Free Software Foundation; either version 2 of 20 the License, or (at your option) any later version, together 21 with the eCos exception, as follows: 22 23 As a special exception, if other files instantiate templates or 24 use macros or inline functions from this file, or you compile this 25 file and link it with other works to produce a work based on this 26 file, this file does not by itself cause the resulting work to be 27 covered by the GNU General Public License. However the source code 28 for this file must still be made available in accordance with 29 section (3) of the GNU General Public License v2. 30 31 This exception does not invalidate any other reasons why a work 32 based on this file might be covered by the GNU General Public 33 License. 34 35 You should have received copies of the GNU Lesser General Public 36 License and the GNU General Public License along with this library; 37 if not, see <https://www.gnu.org/licenses/>. 38 */ 39 40 /** 41 * @file src/test/unit/unit_sha256.c 42 * @brief The tests for SHA-256 43 * @author Karlson2k (Evgeny Grin) 44 * @author Christian Grothoff 45 */ 46 47 #include "mhd_sys_options.h" 48 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <stdint.h> 53 54 #include "mhdt_has_param.h" 55 56 #include "../mhd2/mhd_sha256.h" 57 58 #define SHA256_DIGEST_STRING_SIZE (mhd_SHA256_DIGEST_SIZE * 2 + 1) 59 60 /** 61 * Verbose output? 62 */ 63 static int verbose; 64 65 66 /* Helper function to convert hex string to binary */ 67 static size_t 68 hex2bin (const char *hex, 69 uint8_t *bin, 70 size_t max_len) 71 { 72 size_t len = strlen (hex) / 2; 73 if (len > max_len) 74 len = max_len; 75 76 for (size_t i = 0; i < len; i++) 77 { 78 sscanf (hex + 2 * i, "%2hhx", &bin[i]); 79 } 80 return len; 81 } 82 83 84 /* Helper function to compare digest with expected hex string */ 85 static int 86 check_digest (const uint8_t *digest, 87 size_t digest_len, 88 const char *expected_hex, 89 const char *test_name) 90 { 91 uint8_t expected[64]; 92 size_t expected_len = hex2bin (expected_hex, expected, sizeof(expected)); 93 94 if (expected_len != digest_len) 95 { 96 printf ("FAIL: %s - length mismatch\n", test_name); 97 return 0; 98 } 99 100 if (memcmp (digest, expected, digest_len) != 0) 101 { 102 printf ("FAIL: %s\n", test_name); 103 printf (" Expected: %s\n", expected_hex); 104 printf (" Got: "); 105 for (size_t i = 0; i < digest_len; i++) 106 { 107 printf ("%02x", digest[i]); 108 } 109 printf ("\n"); 110 return 0; 111 } 112 if (verbose) 113 printf ("PASS: %s\n", 114 test_name); 115 return 1; 116 } 117 118 119 struct str_with_len 120 { 121 const char *const str; 122 const size_t len; 123 }; 124 125 #define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1} 126 127 struct data_unit1 128 { 129 const struct str_with_len str_l; 130 const uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 131 }; 132 133 static const struct data_unit1 data_units1[] = { 134 {D_STR_W_LEN ("abc"), 135 {0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 136 0x5d, 0xae, 0x22, 0x23, 137 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 138 0xf2, 0x00, 0x15, 0xad}}, 139 {D_STR_W_LEN ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), 140 {0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 141 0x0c, 0x3e, 0x60, 0x39, 142 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 143 0x19, 0xdb, 0x06, 0xc1}}, 144 {D_STR_W_LEN (""), 145 {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 146 0x99, 0x6f, 0xb9, 0x24, 147 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 148 0x78, 0x52, 0xb8, 0x55}}, 149 {D_STR_W_LEN ("1234567890!@~%&$@#{}[]\\/!?`."), 150 {0x2f, 0xad, 0x7a, 0xff, 0x7d, 0xfe, 0xcd, 0x78, 0xe4, 0xa6, 0xf3, 0x85, 151 0x97, 0x9d, 0xdc, 0x39, 152 0x55, 0x24, 0x35, 0x4a, 0x00, 0x6f, 0x42, 0x72, 0x41, 0xc1, 0x52, 0xa7, 153 0x01, 0x0b, 0x2c, 0x41}}, 154 {D_STR_W_LEN ("Simple string."), 155 {0x01, 0x73, 0x17, 0xc4, 0x0a, 0x9a, 0x0e, 0x81, 0xb3, 0xa4, 0xb1, 0x8e, 156 0xe9, 0xd6, 0xc2, 0xdf, 157 0xfa, 0x7d, 0x53, 0x4e, 0xa1, 0xda, 0xb2, 0x5a, 0x75, 0xbb, 0x2c, 0x30, 158 0x2f, 0x5f, 0x7a, 0xf4}}, 159 {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyz"), 160 {0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44, 161 0x7c, 0x66, 0xc9, 0x52, 162 0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2, 163 0xda, 0xf1, 0x8b, 0x73}}, 164 {D_STR_W_LEN ("zyxwvutsrqponMLKJIHGFEDCBA"), 165 {0xce, 0x7d, 0xde, 0xb6, 0x1f, 0x7c, 0x1d, 0x83, 0x7c, 0x60, 0xd8, 0x36, 166 0x73, 0x82, 0xac, 0x92, 167 0xca, 0x37, 0xfd, 0x72, 0x8b, 0x0c, 0xd1, 0x6c, 0x55, 0xd5, 0x88, 0x98, 168 0x24, 0xfa, 0x16, 0xf2}}, 169 {D_STR_W_LEN ("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA" \ 170 "abcdefghijklmnopqrstuvwxyzzyxwvutsrqponMLKJIHGFEDCBA"), 171 {0x27, 0xd1, 0xe8, 0xbc, 0x6a, 0x79, 0x16, 0x83, 0x61, 0x73, 0xa9, 0xa8, 172 0x9b, 0xaf, 0xaf, 0xcf, 173 0x47, 0x4d, 0x09, 0xef, 0x6d, 0x50, 0x35, 0x12, 0x25, 0x72, 0xd8, 0x68, 174 0xdc, 0x1f, 0xd2, 0xf4}}, 175 {D_STR_W_LEN ("/long/long/long/long/long/long/long/long/long/long/long" \ 176 "/long/long/long/long/long/long/long/long/long/long/long" \ 177 "/long/long/long/long/long/long/long/long/long/long/long" \ 178 "/long/long/long/long/long/long/long/long/long/long/long" \ 179 "/long/long/long/long/long/long/long/long/long/long/long" \ 180 "/long/long/long/long/long/long/long/long/long/long/long" \ 181 "/long/long/long/long/path?with%20some=parameters"), 182 {0x73, 0x85, 0xc5, 0xb9, 0x8f, 0xaf, 0x7d, 0x5e, 0xad, 0xd8, 0x0b, 0x8e, 183 0x12, 0xdb, 0x28, 0x60, 0xc7, 0xc7, 0x55, 0x05, 0x2f, 0x7c, 0x6f, 0xfa, 184 0xd1, 0xe3, 0xe1, 0x7b, 0x04, 0xd4, 0xb0, 0x21}} 185 }; 186 187 static const size_t units1_num = sizeof(data_units1) / sizeof(data_units1[0]); 188 189 struct bin_with_len 190 { 191 const uint8_t bin[512]; 192 const size_t len; 193 }; 194 195 struct data_unit2 196 { 197 const struct bin_with_len bin_l; 198 const uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 199 }; 200 201 /* Size must be less than 512 bytes! */ 202 static const struct data_unit2 data_units2[] = { 203 { { {97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 204 112, 113, 114, 115, 116, 205 117, 118, 119, 120, 121, 122}, 26}, /* a..z ASCII sequence */ 206 {0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44, 207 0x7c, 0x66, 0xc9, 0x52, 208 0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2, 209 0xda, 0xf1, 0x8b, 0x73}}, 210 { { {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 211 65, 65, 65, 65, 65, 65, 212 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 213 65, 65, 65, 65, 65, 65, 214 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 215 65, 65, 65, 65, 65, 65}, 72 },/* 'A' x 72 times */ 216 {0x6a, 0x6d, 0x69, 0x1a, 0xc9, 0xba, 0x70, 0x95, 0x50, 0x46, 0x75, 0x7c, 217 0xd6, 0x85, 0xb6, 0x25, 218 0x77, 0x73, 0xff, 0x3a, 0xd9, 0x3f, 0x43, 0xd4, 0xd4, 0x81, 0x2c, 0x5b, 219 0x10, 0x6f, 0x4b, 0x5b}}, 220 { { {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 221 37, 38, 39, 40, 41, 42, 222 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 223 61, 62, 63, 64, 65, 66, 67, 224 68, 69, 70, 71, 72, 73}, 55}, /* 19..73 sequence */ 225 {0x06, 0xe4, 0xb3, 0x9e, 0xf1, 0xfb, 0x6c, 0xcf, 0xd7, 0x3f, 0x50, 0x9e, 226 0xf4, 0x16, 0x17, 0xd4, 227 0x63, 0x7c, 0x39, 0x1e, 0xa8, 0x0f, 0xa9, 0x88, 0x03, 0x44, 0x98, 0x0e, 228 0x95, 0x81, 0xf0, 0x2a}}, 229 { { {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 230 26, 27, 28, 29, 30, 31, 231 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 232 50, 51, 52, 53, 54, 55, 56, 233 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69}, 63}, /* 7..69 sequence */ 234 {0x4a, 0xd3, 0xc6, 0x87, 0x1f, 0xd1, 0xc5, 0xe2, 0x3e, 0x52, 0xdc, 0x22, 235 0xd1, 0x10, 0xd2, 0x05, 236 0x15, 0x23, 0xcd, 0x15, 0xac, 0x24, 0x88, 0x26, 0x02, 0x00, 0x70, 0x78, 237 0x9f, 0x17, 0xf8, 0xd9}}, 238 { { {38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 239 56, 57, 58, 59, 60, 61, 240 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 241 80, 81, 82, 83, 84, 85, 86, 242 87, 88, 89, 90, 91, 92}, 55}, /* 38..92 sequence */ 243 {0xe6, 0x03, 0x0f, 0xc9, 0x0d, 0xca, 0x0c, 0x26, 0x41, 0xcf, 0x43, 0x27, 244 0xec, 0xd6, 0x28, 0x2a, 245 0x98, 0x24, 0x55, 0xd3, 0x5a, 0xed, 0x8b, 0x32, 0x19, 0x78, 0xeb, 0x83, 246 0x1d, 0x19, 0x92, 0x79}}, 247 { { {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 248 21, 22, 23, 24, 25, 26, 27, 249 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 250 46, 47, 48, 49, 50, 51, 52, 251 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 252 71, 72}, 253 72},/* 1..72 sequence */ 254 {0x87, 0xa2, 0xfa, 0x2e, 0xec, 0x53, 0x05, 0x3c, 0xb1, 0xee, 0x07, 0xd7, 255 0x59, 0x70, 0xf6, 0x50, 256 0xcd, 0x9d, 0xc5, 0x8b, 0xdc, 0xb8, 0x65, 0x30, 0x4f, 0x70, 0x82, 0x9e, 257 0xbd, 0xe2, 0x7d, 0xac}}, 258 { { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 259 21, 22, 23, 24, 25, 26, 260 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 261 45, 46, 47, 48, 49, 50, 51, 262 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 263 70, 71, 72, 73, 74, 75, 76, 264 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 265 95, 96, 97, 98, 99, 100, 266 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 267 115, 116, 117, 118, 119, 120, 268 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 269 135, 136, 137, 138, 139, 140, 270 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 271 155, 156, 157, 158, 159, 160, 272 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 273 175, 176, 177, 178, 179, 180, 274 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 275 195, 196, 197, 198, 199, 200, 276 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 277 215, 216, 217, 218, 219, 220, 278 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 279 235, 236, 237, 238, 239, 240, 280 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 281 255}, 256}, /* 0..255 sequence */ 282 {0x40, 0xaf, 0xf2, 0xe9, 0xd2, 0xd8, 0x92, 0x2e, 0x47, 0xaf, 0xd4, 0x64, 283 0x8e, 0x69, 0x67, 0x49, 284 0x71, 0x58, 0x78, 0x5f, 0xbd, 0x1d, 0xa8, 0x70, 0xe7, 0x11, 0x02, 0x66, 285 0xbf, 0x94, 0x48, 0x80}}, 286 { { {199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 287 185, 184, 183, 182, 181, 180, 288 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 289 165, 164, 163, 162, 161, 160, 290 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 291 145, 144, 143, 142, 141, 140, 292 139}, 61}, /* 199..139 sequence */ 293 {0x85, 0xf8, 0xa2, 0x83, 0xd6, 0x3c, 0x76, 0x8e, 0xea, 0x8f, 0x1c, 0x57, 294 0x2d, 0x85, 0xb6, 0xff, 295 0xd8, 0x33, 0x57, 0x62, 0x1d, 0x37, 0xae, 0x0e, 0xfc, 0x22, 0xd3, 0xd5, 296 0x8f, 0x53, 0x21, 0xb7}}, 297 { { {255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 298 241, 240, 239, 238, 237, 236, 299 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 300 221, 220, 219, 218, 217, 216, 301 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 302 201, 200, 199, 198, 197, 196, 303 195, 194, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 304 181, 180, 179, 178, 177, 176, 305 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 306 161, 160, 159, 158, 157, 156, 307 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, 143, 142, 308 141, 140, 139, 138, 137, 136, 309 135, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, 310 121, 120, 119, 118, 117, 116, 311 115, 114, 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 312 101, 100, 99, 98, 97, 96, 95, 313 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 314 76, 75, 74, 73, 72, 71, 70, 315 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 316 51, 50, 49, 48, 47, 46, 45, 317 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 318 26, 25, 24, 23, 22, 21, 20, 319 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, 255}, /* 255..1 sequence */ 320 {0x61, 0x86, 0x96, 0xab, 0x3e, 0xaa, 0x0e, 0x64, 0xb2, 0xf7, 0x2d, 0x75, 321 0x47, 0x5a, 0x14, 0x97, 322 0xa3, 0x3d, 0x59, 0xa4, 0x08, 0xd9, 0x9e, 0x73, 0xf2, 0x78, 0x00, 0x5b, 323 0x4b, 0x55, 0xca, 0x43}}, 324 { { {41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233, 325 235, 179, 166, 219, 60, 135, 326 12, 62, 153, 36, 94, 13, 28, 6, 183, 71, 222, 179, 18, 77, 200, 67, 187, 327 139, 166, 31, 3, 90, 125, 9, 328 56, 37, 31, 93, 212, 203, 252, 150, 245, 69, 59, 19, 13, 137, 10, 28, 329 219, 174, 50, 32, 154, 80, 238, 330 64, 120, 54, 253, 18, 73, 50, 246, 158, 125, 73, 220, 173, 79, 20, 242, 331 68, 64, 102, 208, 107, 196, 332 48, 183, 50, 59, 161, 34, 246, 34, 145, 157, 225, 139, 31, 218, 176, 202, 333 153, 2, 185, 114, 157, 73, 334 44, 128, 126, 197, 153, 213, 233, 128, 178, 234, 201, 204, 83, 191, 103, 335 214, 191, 20, 214, 126, 45, 336 220, 142, 102, 131, 239, 87, 73, 97, 255, 105, 143, 97, 205, 209, 30, 337 157, 156, 22, 114, 114, 230, 338 29, 240, 132, 79, 74, 119, 2, 215, 232, 57, 44, 83, 203, 201, 18, 30, 51, 339 116, 158, 12, 244, 213, 340 212, 159, 212, 164, 89, 126, 53, 207, 50, 34, 244, 204, 207, 211, 144, 341 45, 72, 211, 143, 117, 230, 342 217, 29, 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212, 343 97, 141, 190, 123, 5, 21, 7, 344 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177, 133, 62, 105, 21, 345 248, 70, 106, 4, 150, 115, 346 14, 217, 22, 47, 103, 104, 212, 247, 74, 74, 208, 87, 104}, 255}, /* pseudo-random data */ 347 {0x08, 0x7f, 0x86, 0xac, 0xe2, 0x2e, 0x28, 0x56, 0x74, 0x53, 0x4f, 0xc0, 348 0xfb, 0xb8, 0x79, 0x57, 349 0xc5, 0xc8, 0xd1, 0xb7, 0x47, 0xb7, 0xd9, 0xea, 0x97, 0xa8, 0x67, 0xe9, 350 0x26, 0x93, 0xee, 0xa3}} 351 }; 352 353 static const size_t units2_num = sizeof(data_units2) / sizeof(data_units2[0]); 354 355 356 /* 357 * Helper functions 358 */ 359 360 /** 361 * Print bin as hex 362 * 363 * @param bin binary data 364 * @param len number of bytes in bin 365 * @param hex pointer to len*2+1 bytes buffer 366 */ 367 static void 368 bin2hex (const uint8_t *bin, 369 size_t len, 370 char *hex) 371 { 372 while (len-- > 0) 373 { 374 unsigned int b1, b2; 375 b1 = (*bin >> 4) & 0xf; 376 *hex++ = (char)((b1 > 9) ? (b1 + 'A' - 10) : (b1 + '0')); 377 b2 = *bin++ & 0xf; 378 *hex++ = (char)((b2 > 9) ? (b2 + 'A' - 10) : (b2 + '0')); 379 } 380 *hex = 0; 381 } 382 383 384 static unsigned int 385 check_result (const char *test_name, 386 unsigned int check_num, 387 const uint8_t calculated[mhd_SHA256_DIGEST_SIZE], 388 const uint8_t expected[mhd_SHA256_DIGEST_SIZE]) 389 { 390 int failed = (0 != 391 memcmp (calculated, 392 expected, 393 mhd_SHA256_DIGEST_SIZE)); 394 395 check_num++; /* Print 1-based numbers */ 396 if (failed) 397 { 398 char calc_str[SHA256_DIGEST_STRING_SIZE]; 399 char expc_str[SHA256_DIGEST_STRING_SIZE]; 400 bin2hex (calculated, mhd_SHA256_DIGEST_SIZE, calc_str); 401 bin2hex (expected, mhd_SHA256_DIGEST_SIZE, expc_str); 402 fprintf (stderr, 403 "FAILED: %s check %u: calculated digest %s, expected digest %s.\n", 404 test_name, check_num, calc_str, expc_str); 405 fflush (stderr); 406 return 1; 407 } 408 if (verbose) 409 { 410 char calc_str[SHA256_DIGEST_STRING_SIZE]; 411 bin2hex (calculated, mhd_SHA256_DIGEST_SIZE, calc_str); 412 printf ("PASSED: %s check %u: calculated digest %s " 413 "matches expected digest.\n", 414 test_name, check_num, calc_str); 415 fflush (stdout); 416 } 417 return 0; 418 } 419 420 421 /* 422 * Tests 423 */ 424 425 /* Calculated SHA-256 as one pass for whole data */ 426 static unsigned int 427 test1_str (void) 428 { 429 unsigned int num_failed = 0; 430 unsigned int i; 431 struct mhd_Sha256Ctx ctx; 432 433 mhd_SHA256_init (&ctx); 434 for (i = 0; i < units1_num; i++) 435 { 436 uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 437 438 if (0 != data_units1[i].str_l.len) 439 mhd_SHA256_update (&ctx, 440 data_units1[i].str_l.len, 441 (const uint8_t *)data_units1[i].str_l.str); 442 mhd_SHA256_finish_reset (&ctx, 443 digest); 444 if (mhd_SHA256_has_err (&ctx)) 445 { 446 fprintf (stderr, 447 "External hashing error: %d.\n", 448 mhd_SHA256_get_err (&ctx)); 449 mhd_SHA256_deinit (&ctx); 450 exit (99); 451 } 452 num_failed += check_result (MHD_FUNC_, i, digest, 453 data_units1[i].digest); 454 } 455 mhd_SHA256_deinit (&ctx); 456 return num_failed; 457 } 458 459 460 static unsigned int 461 test1_bin (void) 462 { 463 unsigned int num_failed = 0; 464 unsigned int i; 465 struct mhd_Sha256Ctx ctx; 466 467 mhd_SHA256_init (&ctx); 468 for (i = 0; i < units2_num; i++) 469 { 470 uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 471 472 mhd_SHA256_update (&ctx, 473 data_units2[i].bin_l.len, 474 data_units2[i].bin_l.bin); 475 mhd_SHA256_finish_reset (&ctx, digest); 476 if (mhd_SHA256_has_err (&ctx)) 477 { 478 fprintf (stderr, 479 "External hashing error: %d.\n", 480 mhd_SHA256_get_err (&ctx)); 481 mhd_SHA256_deinit (&ctx); 482 exit (99); 483 } 484 num_failed += check_result (MHD_FUNC_, i, digest, 485 data_units2[i].digest); 486 } 487 mhd_SHA256_deinit (&ctx); 488 return num_failed; 489 } 490 491 492 /* Calculated SHA-256 as two iterations for whole data */ 493 static unsigned int 494 test2_str (void) 495 { 496 unsigned int num_failed = 0; 497 unsigned int i; 498 struct mhd_Sha256Ctx ctx; 499 500 mhd_SHA256_init (&ctx); 501 for (i = 0; i < units1_num; i++) 502 { 503 uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 504 size_t part_s = data_units1[i].str_l.len / 4; 505 506 if (0 != part_s) 507 mhd_SHA256_update (&ctx, 508 part_s, 509 (const uint8_t *)data_units1[i].str_l.str); 510 if (data_units1[i].str_l.len != part_s) 511 mhd_SHA256_update (&ctx, 512 data_units1[i].str_l.len - part_s, 513 (const uint8_t *)data_units1[i].str_l.str + part_s); 514 mhd_SHA256_finish_reset (&ctx, digest); 515 if (mhd_SHA256_has_err (&ctx)) 516 { 517 fprintf (stderr, 518 "External hashing error: %d.\n", 519 mhd_SHA256_get_err (&ctx)); 520 mhd_SHA256_deinit (&ctx); 521 exit (99); 522 } 523 num_failed += check_result (MHD_FUNC_, i, digest, 524 data_units1[i].digest); 525 } 526 mhd_SHA256_deinit (&ctx); 527 return num_failed; 528 } 529 530 531 static unsigned int 532 test2_bin (void) 533 { 534 unsigned int num_failed = 0; 535 unsigned int i; 536 struct mhd_Sha256Ctx ctx; 537 538 mhd_SHA256_init (&ctx); 539 for (i = 0; i < units2_num; i++) 540 { 541 uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 542 size_t part_s = data_units2[i].bin_l.len * 2 / 3; 543 544 mhd_SHA256_update (&ctx, 545 part_s, 546 data_units2[i].bin_l.bin); 547 mhd_SHA256_update (&ctx, 548 data_units2[i].bin_l.len - part_s, 549 data_units2[i].bin_l.bin + part_s); 550 mhd_SHA256_finish_reset (&ctx, 551 digest); 552 if (mhd_SHA256_has_err (&ctx)) 553 { 554 fprintf (stderr, 555 "External hashing error: %d.\n", 556 mhd_SHA256_get_err (&ctx)); 557 mhd_SHA256_deinit (&ctx); 558 exit (99); 559 } 560 num_failed += check_result (MHD_FUNC_, i, digest, 561 data_units2[i].digest); 562 } 563 mhd_SHA256_deinit (&ctx); 564 return num_failed; 565 } 566 567 568 /* Use data set number 7 as it has the longest sequence */ 569 #define DATA_POS 6 570 #define MAX_OFFSET 31 571 572 static unsigned int 573 test_unaligned (void) 574 { 575 unsigned int num_failed = 0; 576 unsigned int offset; 577 uint8_t *buf; 578 uint8_t *digest_buf; 579 struct mhd_Sha256Ctx ctx; 580 581 const struct data_unit2 *const tdata = data_units2 + DATA_POS; 582 583 mhd_SHA256_init (&ctx); 584 buf = (uint8_t *)malloc (tdata->bin_l.len + MAX_OFFSET); 585 digest_buf = (uint8_t *)malloc (mhd_SHA256_DIGEST_SIZE + MAX_OFFSET); 586 if ((NULL == buf) || (NULL == digest_buf)) 587 { 588 fprintf (stderr, 589 "FAIL: test_unaligned - memory allocation failed.\n"); 590 mhd_SHA256_deinit (&ctx); 591 free (digest_buf); 592 free (buf); 593 exit (99); 594 } 595 596 for (offset = MAX_OFFSET; offset >= 1; --offset) 597 { 598 uint8_t *unaligned_digest; 599 uint8_t *unaligned_buf; 600 601 unaligned_buf = buf + offset; 602 memcpy (unaligned_buf, tdata->bin_l.bin, tdata->bin_l.len); 603 unaligned_digest = digest_buf + MAX_OFFSET - offset; 604 memset (unaligned_digest, 0, mhd_SHA256_DIGEST_SIZE); 605 606 mhd_SHA256_update (&ctx, 607 tdata->bin_l.len, 608 unaligned_buf); 609 mhd_SHA256_finish_reset (&ctx, 610 unaligned_digest); 611 if (mhd_SHA256_has_err (&ctx)) 612 { 613 fprintf (stderr, 614 "External hashing error: %d.\n", 615 mhd_SHA256_get_err (&ctx)); 616 mhd_SHA256_deinit (&ctx); 617 free (digest_buf); 618 free (buf); 619 exit (99); 620 } 621 num_failed += check_result (MHD_FUNC_, MAX_OFFSET - offset, 622 unaligned_digest, tdata->digest); 623 } 624 free (digest_buf); 625 free (buf); 626 mhd_SHA256_deinit (&ctx); 627 return num_failed; 628 } 629 630 631 int 632 main (int argc, 633 char **argv) 634 { 635 struct Test 636 { 637 const char *name; 638 const char *input; 639 const char *digest; 640 } tests[] = { 641 { 642 "Empty string (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)", 643 "", 644 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" 645 }, 646 { 647 "d3 (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)", 648 "d3", 649 "28969cdfa74a12c82f3bad960b0b000aca2ac329deea5c2328ebc6f2ba9802c1" 650 }, 651 { 652 "11af (https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/shs/shabytetestvectors.zip)", 653 "11af", 654 "5ca7133fa735326081558ac312c620eeca9970d1e70a4b95533d956f072d1f98" 655 }, 656 { 657 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq (https://di-mgt.com.au/sha_testvectors.html)", 658 "6162636462636465636465666465666765666768666768696768696a68696a6b696a6b6c6a6b6c6d6b6c6d6e6c6d6e6f6d6e6f706e6f7071", 659 "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" 660 }, 661 { 662 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu (https://di-mgt.com.au/sha_testvectors.html)", 663 "61626364656667686263646566676869636465666768696a6465666768696a6b65666768696a6b6c666768696a6b6c6d6768696a6b6c6d6e68696a6b6c6d6e6f696a6b6c6d6e6f706a6b6c6d6e6f70716b6c6d6e6f7071726c6d6e6f707172736d6e6f70717273746e6f707172737475", 664 "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" 665 }, 666 { "message digest", 667 "6d65737361676520646967657374", 668 "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650" }, 669 { "One byte 0x00", 670 "00", 671 "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d" }, 672 { "Two bytes 0x00 0x00", 673 "0000", 674 "96a296d224f285c67bee93c30f8a309157f0daa35dc5b87e410b78630a09cfc7" } 675 }; 676 struct mhd_Sha256Ctx ctx; 677 uint8_t digest[mhd_SHA256_DIGEST_SIZE]; 678 uint8_t data[1024]; 679 size_t data_len; 680 const char *test_name; 681 unsigned int i; 682 unsigned int passed = 0; 683 unsigned int total = 0; 684 unsigned int num_failed; 685 686 if (mhdt_has_param (argc, argv, "-v") 687 || mhdt_has_param (argc, argv, "--verbose")) 688 verbose = 1; 689 690 691 for (total = 0; total < sizeof(tests) / sizeof(tests[0]); ++total) 692 { 693 const struct Test *t = &tests[total]; 694 695 mhd_SHA256_init (&ctx); 696 if (!mhd_SHA256_has_err (&ctx)) 697 { 698 data_len = hex2bin (t->input, 699 data, 700 sizeof(data)); 701 if (0 != data_len) 702 mhd_SHA256_update (&ctx, 703 data_len, 704 data); 705 mhd_SHA256_finish (&ctx, 706 digest); 707 if (!mhd_SHA256_has_err (&ctx)) 708 { 709 if (check_digest (digest, 710 mhd_SHA256_DIGEST_SIZE, 711 t->digest, 712 t->name)) 713 passed++; 714 } 715 else 716 { 717 fprintf (stderr, 718 "FAIL: %s - digest function failed due to backend error: " \ 719 "%d.\n", 720 t->name, 721 mhd_SHA256_get_err (&ctx)); 722 mhd_SHA256_deinit (&ctx); 723 exit (99); 724 } 725 } 726 else 727 { 728 fprintf (stderr, 729 "FAIL: %s - backend initialisation error: %d.\n", 730 t->name, 731 mhd_SHA256_get_err (&ctx)); 732 mhd_SHA256_deinit (&ctx); 733 exit (99); 734 } 735 mhd_SHA256_deinit (&ctx); 736 } 737 738 /* 739 * Test update functionality 740 */ 741 total++; 742 test_name = "Multi-update: a + b + c"; 743 mhd_SHA256_init (&ctx); 744 if (!mhd_SHA256_has_err (&ctx)) 745 { 746 data[0] = 'a'; 747 mhd_SHA256_update (&ctx, 748 1, 749 data); 750 data[0] = 'b'; 751 mhd_SHA256_update (&ctx, 752 1, 753 data); 754 mhd_SHA256_update (&ctx, 755 0, /* Empty data - valid for unit-tests only */ 756 data); 757 data[0] = 'c'; 758 mhd_SHA256_update (&ctx, 759 1, 760 data); 761 mhd_SHA256_finish (&ctx, 762 digest); 763 if (!mhd_SHA256_has_err (&ctx)) 764 { 765 if (check_digest (digest, 766 mhd_SHA256_DIGEST_SIZE, 767 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 768 test_name)) 769 passed++; 770 } 771 else 772 { 773 fprintf (stderr, 774 "FAIL: %s - backend error: %d.\n", 775 test_name, 776 mhd_SHA256_get_err (&ctx)); 777 mhd_SHA256_deinit (&ctx); 778 exit (99); 779 } 780 } 781 else 782 { 783 fprintf (stderr, 784 "FAIL: %s - backend initialisation error: %d.\n", 785 test_name, 786 mhd_SHA256_get_err (&ctx)); 787 mhd_SHA256_deinit (&ctx); 788 exit (99); 789 } 790 mhd_SHA256_deinit (&ctx); 791 792 /* 793 * Tests finish_reset and reuse of context 794 */ 795 total++; 796 test_name = "Reset and reuse context"; 797 mhd_SHA256_init (&ctx); 798 if (!mhd_SHA256_has_err (&ctx)) 799 { 800 /* First hash */ 801 data_len = hex2bin ("616263", 802 data, 803 sizeof(data)); /* "abc" */ 804 mhd_SHA256_update (&ctx, 805 data_len, 806 data); 807 mhd_SHA256_finish_reset (&ctx, digest); 808 809 if (mhd_SHA256_has_err (&ctx)) 810 { 811 fprintf (stderr, 812 "FAIL: %s - backend error after first hash: %d.\n", 813 test_name, 814 mhd_SHA256_get_err (&ctx)); 815 mhd_SHA256_deinit (&ctx); 816 exit (99); 817 } 818 if (check_digest (digest, 819 mhd_SHA256_DIGEST_SIZE, 820 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 821 "Reset and reuse context: first hash")) 822 passed++; 823 824 /* Second hash on same context */ 825 total++; 826 data_len = hex2bin ("61", 827 data, 828 sizeof(data)); /* "a" */ 829 mhd_SHA256_update (&ctx, 830 data_len, 831 data); 832 mhd_SHA256_finish (&ctx, 833 digest); 834 835 if (!mhd_SHA256_has_err (&ctx)) 836 { 837 if (check_digest (digest, 838 mhd_SHA256_DIGEST_SIZE, 839 "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", 840 "Reset and reuse context: second hash")) 841 passed++; 842 } 843 else 844 { 845 fprintf (stderr, 846 "FAIL: %s - backend error after second hash: %d.\n", 847 test_name, 848 mhd_SHA256_get_err (&ctx)); 849 mhd_SHA256_deinit (&ctx); 850 exit (99); 851 } 852 } 853 else 854 { 855 fprintf (stderr, 856 "FAIL: %s - backend initialisation error: %d.\n", 857 test_name, 858 mhd_SHA256_get_err (&ctx)); 859 mhd_SHA256_deinit (&ctx); 860 exit (99); 861 } 862 mhd_SHA256_deinit (&ctx); 863 864 /* 865 * Test finish_deinit functionality 866 */ 867 total++; 868 test_name = "Finish and deinitialise context"; 869 mhd_SHA256_init (&ctx); 870 if (mhd_SHA256_has_err (&ctx)) 871 { 872 fprintf (stderr, 873 "FAIL: %s - backend initialisation error: %d.\n", 874 test_name, 875 mhd_SHA256_get_err (&ctx)); 876 mhd_SHA256_deinit (&ctx); 877 exit (99); 878 } 879 data_len = hex2bin ("616263", 880 data, 881 sizeof(data)); /* "abc" */ 882 mhd_SHA256_update (&ctx, 883 data_len, 884 data); 885 mhd_SHA256_finish_deinit (&ctx, 886 digest); 887 if (mhd_SHA256_has_err (&ctx)) 888 { 889 fprintf (stderr, 890 "FAIL: %s - backend error: %d.\n", 891 test_name, 892 mhd_SHA256_get_err (&ctx)); 893 exit (99); 894 } 895 if (check_digest (digest, 896 mhd_SHA256_DIGEST_SIZE, 897 "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 898 test_name)) 899 passed++; 900 901 /* 902 * Test hashing of a long multi-block stream of data 903 */ 904 total++; 905 test_name = "One million repetitions of 'a'"; 906 mhd_SHA256_init (&ctx); 907 if (mhd_SHA256_has_err (&ctx)) 908 { 909 fprintf (stderr, 910 "FAIL: %s - backend initialisation error: %d.\n", 911 test_name, 912 mhd_SHA256_get_err (&ctx)); 913 mhd_SHA256_deinit (&ctx); 914 exit (99); 915 } 916 memset (data, 'a', 1000); 917 for (i = 0; i < 1000; ++i) 918 mhd_SHA256_update (&ctx, 919 1000, 920 data); 921 mhd_SHA256_finish (&ctx, 922 digest); 923 if (mhd_SHA256_has_err (&ctx)) 924 { 925 fprintf (stderr, 926 "FAIL: %s - backend error: %d.\n", 927 test_name, 928 mhd_SHA256_get_err (&ctx)); 929 mhd_SHA256_deinit (&ctx); 930 exit (99); 931 } 932 if (check_digest (digest, 933 mhd_SHA256_DIGEST_SIZE, 934 "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", 935 test_name)) 936 passed++; 937 mhd_SHA256_deinit (&ctx); 938 939 num_failed = total - passed; 940 941 num_failed += test1_str (); 942 num_failed += test1_bin (); 943 944 num_failed += test2_str (); 945 num_failed += test2_bin (); 946 947 num_failed += test_unaligned (); 948 949 950 if ((0 != num_failed) || verbose) 951 fprintf (stderr, 952 "Result: %u tests failed\n", 953 num_failed); 954 955 return (0 == num_failed) ? 0 : 1; 956 }