1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://opensource.org/licenses/CDDL-1.0. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2013 Saso Kiselkov. All rights reserved. 24 */ 25 26 /* 27 * This is just to keep the compiler happy about sys/time.h not declaring 28 * gettimeofday due to -D_KERNEL (we can do this since we're actually 29 * running in userspace, but we need -D_KERNEL for the remaining Skein code). 30 */ 31 32 #include <sys/skein.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <stdio.h> 36 #include <sys/time.h> 37 #include <sys/stdtypes.h> 38 39 /* 40 * Skein test suite using values from the Skein V1.3 specification found at: 41 * http://www.skein-hash.info/sites/default/files/skein1.3.pdf 42 */ 43 44 /* 45 * Test messages from the Skein spec, Appendix C. 46 */ 47 static const uint8_t test_msg0[] = { 48 0xFF 49 }; 50 51 static const uint8_t test_msg1[] = { 52 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 53 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 54 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 55 0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0 56 }; 57 58 static const uint8_t test_msg2[] = { 59 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 60 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 61 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 62 0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 63 0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8, 64 0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0, 65 0xCF, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8, 66 0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0 67 }; 68 69 static const uint8_t test_msg3[] = { 70 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 71 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 72 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 73 0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 74 0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8, 75 0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0, 76 0xCF, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8, 77 0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0, 78 0xBF, 0xBE, 0xBD, 0xBC, 0xBB, 0xBA, 0xB9, 0xB8, 79 0xB7, 0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1, 0xB0, 80 0xAF, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, 0xA8, 81 0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1, 0xA0, 82 0x9F, 0x9E, 0x9D, 0x9C, 0x9B, 0x9A, 0x99, 0x98, 83 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 84 0x8F, 0x8E, 0x8D, 0x8C, 0x8B, 0x8A, 0x89, 0x88, 85 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80 86 }; 87 88 static const uint8_t test_msg4[] = { 89 0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 90 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0, 91 0xEF, 0xEE, 0xED, 0xEC, 0xEB, 0xEA, 0xE9, 0xE8, 92 0xE7, 0xE6, 0xE5, 0xE4, 0xE3, 0xE2, 0xE1, 0xE0, 93 0xDF, 0xDE, 0xDD, 0xDC, 0xDB, 0xDA, 0xD9, 0xD8, 94 0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xD0, 95 0xCF, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC8, 96 0xC7, 0xC6, 0xC5, 0xC4, 0xC3, 0xC2, 0xC1, 0xC0, 97 0xBF, 0xBE, 0xBD, 0xBC, 0xBB, 0xBA, 0xB9, 0xB8, 98 0xB7, 0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1, 0xB0, 99 0xAF, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, 0xA8, 100 0xA7, 0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1, 0xA0, 101 0x9F, 0x9E, 0x9D, 0x9C, 0x9B, 0x9A, 0x99, 0x98, 102 0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 103 0x8F, 0x8E, 0x8D, 0x8C, 0x8B, 0x8A, 0x89, 0x88, 104 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 105 0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 106 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 107 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 108 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 109 0x5F, 0x5E, 0x5D, 0x5C, 0x5B, 0x5A, 0x59, 0x58, 110 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 111 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 0x48, 112 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 113 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38, 114 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 115 0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28, 116 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 117 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 118 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 119 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 120 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 121 }; 122 123 /* 124 * Test digests from the Skein spec, Appendix C. 125 */ 126 static const uint8_t skein_256_test_digests[][32] = { 127 { 128 /* for test_msg0 */ 129 0x0B, 0x98, 0xDC, 0xD1, 0x98, 0xEA, 0x0E, 0x50, 130 0xA7, 0xA2, 0x44, 0xC4, 0x44, 0xE2, 0x5C, 0x23, 131 0xDA, 0x30, 0xC1, 0x0F, 0xC9, 0xA1, 0xF2, 0x70, 132 0xA6, 0x63, 0x7F, 0x1F, 0x34, 0xE6, 0x7E, 0xD2 133 }, 134 { 135 /* for test_msg1 */ 136 0x8D, 0x0F, 0xA4, 0xEF, 0x77, 0x7F, 0xD7, 0x59, 137 0xDF, 0xD4, 0x04, 0x4E, 0x6F, 0x6A, 0x5A, 0xC3, 138 0xC7, 0x74, 0xAE, 0xC9, 0x43, 0xDC, 0xFC, 0x07, 139 0x92, 0x7B, 0x72, 0x3B, 0x5D, 0xBF, 0x40, 0x8B 140 }, 141 { 142 /* for test_msg2 */ 143 0xDF, 0x28, 0xE9, 0x16, 0x63, 0x0D, 0x0B, 0x44, 144 0xC4, 0xA8, 0x49, 0xDC, 0x9A, 0x02, 0xF0, 0x7A, 145 0x07, 0xCB, 0x30, 0xF7, 0x32, 0x31, 0x82, 0x56, 146 0xB1, 0x5D, 0x86, 0x5A, 0xC4, 0xAE, 0x16, 0x2F 147 } 148 /* no test digests for test_msg3 and test_msg4 */ 149 }; 150 151 static const uint8_t skein_512_test_digests[][64] = { 152 { 153 /* for test_msg0 */ 154 0x71, 0xB7, 0xBC, 0xE6, 0xFE, 0x64, 0x52, 0x22, 155 0x7B, 0x9C, 0xED, 0x60, 0x14, 0x24, 0x9E, 0x5B, 156 0xF9, 0xA9, 0x75, 0x4C, 0x3A, 0xD6, 0x18, 0xCC, 157 0xC4, 0xE0, 0xAA, 0xE1, 0x6B, 0x31, 0x6C, 0xC8, 158 0xCA, 0x69, 0x8D, 0x86, 0x43, 0x07, 0xED, 0x3E, 159 0x80, 0xB6, 0xEF, 0x15, 0x70, 0x81, 0x2A, 0xC5, 160 0x27, 0x2D, 0xC4, 0x09, 0xB5, 0xA0, 0x12, 0xDF, 161 0x2A, 0x57, 0x91, 0x02, 0xF3, 0x40, 0x61, 0x7A 162 }, 163 { 164 /* no test vector for test_msg1 */ 165 0, 166 }, 167 { 168 /* for test_msg2 */ 169 0x45, 0x86, 0x3B, 0xA3, 0xBE, 0x0C, 0x4D, 0xFC, 170 0x27, 0xE7, 0x5D, 0x35, 0x84, 0x96, 0xF4, 0xAC, 171 0x9A, 0x73, 0x6A, 0x50, 0x5D, 0x93, 0x13, 0xB4, 172 0x2B, 0x2F, 0x5E, 0xAD, 0xA7, 0x9F, 0xC1, 0x7F, 173 0x63, 0x86, 0x1E, 0x94, 0x7A, 0xFB, 0x1D, 0x05, 174 0x6A, 0xA1, 0x99, 0x57, 0x5A, 0xD3, 0xF8, 0xC9, 175 0xA3, 0xCC, 0x17, 0x80, 0xB5, 0xE5, 0xFA, 0x4C, 176 0xAE, 0x05, 0x0E, 0x98, 0x98, 0x76, 0x62, 0x5B 177 }, 178 { 179 /* for test_msg3 */ 180 0x91, 0xCC, 0xA5, 0x10, 0xC2, 0x63, 0xC4, 0xDD, 181 0xD0, 0x10, 0x53, 0x0A, 0x33, 0x07, 0x33, 0x09, 182 0x62, 0x86, 0x31, 0xF3, 0x08, 0x74, 0x7E, 0x1B, 183 0xCB, 0xAA, 0x90, 0xE4, 0x51, 0xCA, 0xB9, 0x2E, 184 0x51, 0x88, 0x08, 0x7A, 0xF4, 0x18, 0x87, 0x73, 185 0xA3, 0x32, 0x30, 0x3E, 0x66, 0x67, 0xA7, 0xA2, 186 0x10, 0x85, 0x6F, 0x74, 0x21, 0x39, 0x00, 0x00, 187 0x71, 0xF4, 0x8E, 0x8B, 0xA2, 0xA5, 0xAD, 0xB7 188 } 189 /* no test digests for test_msg4 */ 190 }; 191 192 static const uint8_t skein_1024_test_digests[][128] = { 193 { 194 /* for test_msg0 */ 195 0xE6, 0x2C, 0x05, 0x80, 0x2E, 0xA0, 0x15, 0x24, 196 0x07, 0xCD, 0xD8, 0x78, 0x7F, 0xDA, 0x9E, 0x35, 197 0x70, 0x3D, 0xE8, 0x62, 0xA4, 0xFB, 0xC1, 0x19, 198 0xCF, 0xF8, 0x59, 0x0A, 0xFE, 0x79, 0x25, 0x0B, 199 0xCC, 0xC8, 0xB3, 0xFA, 0xF1, 0xBD, 0x24, 0x22, 200 0xAB, 0x5C, 0x0D, 0x26, 0x3F, 0xB2, 0xF8, 0xAF, 201 0xB3, 0xF7, 0x96, 0xF0, 0x48, 0x00, 0x03, 0x81, 202 0x53, 0x1B, 0x6F, 0x00, 0xD8, 0x51, 0x61, 0xBC, 203 0x0F, 0xFF, 0x4B, 0xEF, 0x24, 0x86, 0xB1, 0xEB, 204 0xCD, 0x37, 0x73, 0xFA, 0xBF, 0x50, 0xAD, 0x4A, 205 0xD5, 0x63, 0x9A, 0xF9, 0x04, 0x0E, 0x3F, 0x29, 206 0xC6, 0xC9, 0x31, 0x30, 0x1B, 0xF7, 0x98, 0x32, 207 0xE9, 0xDA, 0x09, 0x85, 0x7E, 0x83, 0x1E, 0x82, 208 0xEF, 0x8B, 0x46, 0x91, 0xC2, 0x35, 0x65, 0x65, 209 0x15, 0xD4, 0x37, 0xD2, 0xBD, 0xA3, 0x3B, 0xCE, 210 0xC0, 0x01, 0xC6, 0x7F, 0xFD, 0xE1, 0x5B, 0xA8 211 }, 212 { 213 /* no test vector for test_msg1 */ 214 0 215 }, 216 { 217 /* no test vector for test_msg2 */ 218 0 219 }, 220 { 221 /* for test_msg3 */ 222 0x1F, 0x3E, 0x02, 0xC4, 0x6F, 0xB8, 0x0A, 0x3F, 223 0xCD, 0x2D, 0xFB, 0xBC, 0x7C, 0x17, 0x38, 0x00, 224 0xB4, 0x0C, 0x60, 0xC2, 0x35, 0x4A, 0xF5, 0x51, 225 0x18, 0x9E, 0xBF, 0x43, 0x3C, 0x3D, 0x85, 0xF9, 226 0xFF, 0x18, 0x03, 0xE6, 0xD9, 0x20, 0x49, 0x31, 227 0x79, 0xED, 0x7A, 0xE7, 0xFC, 0xE6, 0x9C, 0x35, 228 0x81, 0xA5, 0xA2, 0xF8, 0x2D, 0x3E, 0x0C, 0x7A, 229 0x29, 0x55, 0x74, 0xD0, 0xCD, 0x7D, 0x21, 0x7C, 230 0x48, 0x4D, 0x2F, 0x63, 0x13, 0xD5, 0x9A, 0x77, 231 0x18, 0xEA, 0xD0, 0x7D, 0x07, 0x29, 0xC2, 0x48, 232 0x51, 0xD7, 0xE7, 0xD2, 0x49, 0x1B, 0x90, 0x2D, 233 0x48, 0x91, 0x94, 0xE6, 0xB7, 0xD3, 0x69, 0xDB, 234 0x0A, 0xB7, 0xAA, 0x10, 0x6F, 0x0E, 0xE0, 0xA3, 235 0x9A, 0x42, 0xEF, 0xC5, 0x4F, 0x18, 0xD9, 0x37, 236 0x76, 0x08, 0x09, 0x85, 0xF9, 0x07, 0x57, 0x4F, 237 0x99, 0x5E, 0xC6, 0xA3, 0x71, 0x53, 0xA5, 0x78 238 }, 239 { 240 /* for test_msg4 */ 241 0x84, 0x2A, 0x53, 0xC9, 0x9C, 0x12, 0xB0, 0xCF, 242 0x80, 0xCF, 0x69, 0x49, 0x1B, 0xE5, 0xE2, 0xF7, 243 0x51, 0x5D, 0xE8, 0x73, 0x3B, 0x6E, 0xA9, 0x42, 244 0x2D, 0xFD, 0x67, 0x66, 0x65, 0xB5, 0xFA, 0x42, 245 0xFF, 0xB3, 0xA9, 0xC4, 0x8C, 0x21, 0x77, 0x77, 246 0x95, 0x08, 0x48, 0xCE, 0xCD, 0xB4, 0x8F, 0x64, 247 0x0F, 0x81, 0xFB, 0x92, 0xBE, 0xF6, 0xF8, 0x8F, 248 0x7A, 0x85, 0xC1, 0xF7, 0xCD, 0x14, 0x46, 0xC9, 249 0x16, 0x1C, 0x0A, 0xFE, 0x8F, 0x25, 0xAE, 0x44, 250 0x4F, 0x40, 0xD3, 0x68, 0x00, 0x81, 0xC3, 0x5A, 251 0xA4, 0x3F, 0x64, 0x0F, 0xD5, 0xFA, 0x3C, 0x3C, 252 0x03, 0x0B, 0xCC, 0x06, 0xAB, 0xAC, 0x01, 0xD0, 253 0x98, 0xBC, 0xC9, 0x84, 0xEB, 0xD8, 0x32, 0x27, 254 0x12, 0x92, 0x1E, 0x00, 0xB1, 0xBA, 0x07, 0xD6, 255 0xD0, 0x1F, 0x26, 0x90, 0x70, 0x50, 0x25, 0x5E, 256 0xF2, 0xC8, 0xE2, 0x4F, 0x71, 0x6C, 0x52, 0xA5 257 } 258 }; 259 260 int 261 main(int argc, char *argv[]) 262 { 263 boolean_t failed = B_FALSE; 264 uint64_t cpu_mhz = 0; 265 266 if (argc == 2) 267 cpu_mhz = atoi(argv[1]); 268 269 #define SKEIN_ALGO_TEST(_m, mode, diglen, testdigest) \ 270 do { \ 271 Skein ## mode ## _Ctxt_t ctx; \ 272 uint8_t digest[diglen / 8]; \ 273 (void) Skein ## mode ## _Init(&ctx, diglen); \ 274 (void) Skein ## mode ## _Update(&ctx, _m, sizeof (_m)); \ 275 (void) Skein ## mode ## _Final(&ctx, digest); \ 276 (void) printf("Skein" #mode "/" #diglen \ 277 "\tMessage: " #_m "\tResult: "); \ 278 if (memcmp(digest, testdigest, diglen / 8) == 0) { \ 279 (void) printf("OK\n"); \ 280 } else { \ 281 (void) printf("FAILED!\n"); \ 282 failed = B_TRUE; \ 283 } \ 284 } while (0) 285 286 #define SKEIN_PERF_TEST(mode, diglen) \ 287 do { \ 288 Skein ## mode ## _Ctxt_t ctx; \ 289 uint8_t digest[diglen / 8]; \ 290 uint8_t block[131072]; \ 291 uint64_t delta; \ 292 double cpb = 0; \ 293 int i; \ 294 struct timeval start, end; \ 295 memset(block, 0, sizeof (block)); \ 296 (void) gettimeofday(&start, NULL); \ 297 (void) Skein ## mode ## _Init(&ctx, diglen); \ 298 for (i = 0; i < 8192; i++) { \ 299 (void) Skein ## mode ## _Update(&ctx, block, \ 300 sizeof (block)); \ 301 } \ 302 (void) Skein ## mode ## _Final(&ctx, digest); \ 303 (void) gettimeofday(&end, NULL); \ 304 delta = (end.tv_sec * 1000000llu + end.tv_usec) - \ 305 (start.tv_sec * 1000000llu + start.tv_usec); \ 306 if (cpu_mhz != 0) { \ 307 cpb = (cpu_mhz * 1e6 * ((double)delta / \ 308 1000000)) / (8192 * 128 * 1024); \ 309 } \ 310 (void) printf("Skein" #mode "/" #diglen "\t%llu us " \ 311 "(%.02f CPB)\n", (u_longlong_t)delta, cpb); \ 312 } while (0) 313 314 (void) printf("Running algorithm correctness tests:\n"); 315 SKEIN_ALGO_TEST(test_msg0, _256, 256, skein_256_test_digests[0]); 316 SKEIN_ALGO_TEST(test_msg1, _256, 256, skein_256_test_digests[1]); 317 SKEIN_ALGO_TEST(test_msg2, _256, 256, skein_256_test_digests[2]); 318 SKEIN_ALGO_TEST(test_msg0, _512, 512, skein_512_test_digests[0]); 319 SKEIN_ALGO_TEST(test_msg2, _512, 512, skein_512_test_digests[2]); 320 SKEIN_ALGO_TEST(test_msg3, _512, 512, skein_512_test_digests[3]); 321 SKEIN_ALGO_TEST(test_msg0, 1024, 1024, skein_1024_test_digests[0]); 322 SKEIN_ALGO_TEST(test_msg3, 1024, 1024, skein_1024_test_digests[3]); 323 SKEIN_ALGO_TEST(test_msg4, 1024, 1024, skein_1024_test_digests[4]); 324 if (failed) 325 return (1); 326 327 (void) printf("Running performance tests (hashing 1024 MiB of " 328 "data):\n"); 329 SKEIN_PERF_TEST(_256, 256); 330 SKEIN_PERF_TEST(_512, 512); 331 SKEIN_PERF_TEST(1024, 1024); 332 333 return (0); 334 } 335