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 SHA2 code). 30 */ 31 #ifdef _KERNEL 32 #undef _KERNEL 33 #endif 34 35 #include <sys/varargs.h> 36 #include <stdlib.h> 37 #include <strings.h> 38 #include <stdio.h> 39 #include <sys/time.h> 40 #define _SHA2_IMPL 41 #include <sys/sha2.h> 42 43 /* 44 * Test messages from: 45 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf 46 */ 47 48 const char *test_msg0 = "abc"; 49 const char *test_msg1 = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmn" 50 "lmnomnopnopq"; 51 const char *test_msg2 = "abcdefghbcdefghicdefghijdefghijkefghijklfghi" 52 "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; 53 54 /* 55 * Test digests from: 56 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA_All.pdf 57 */ 58 const uint8_t sha256_test_digests[][32] = { 59 { 60 // for test_msg0 61 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 62 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, 63 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 64 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD 65 }, 66 { 67 // for test_msg1 68 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 69 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, 70 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 71 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 72 } 73 // no test vector for test_msg2 74 }; 75 76 const uint8_t sha384_test_digests[][48] = { 77 { 78 // for test_msg0 79 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, 80 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, 81 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, 82 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, 83 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, 84 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 85 }, 86 { 87 // no test vector for test_msg1 88 }, 89 { 90 // for test_msg2 91 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, 92 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, 93 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, 94 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, 95 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, 96 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 97 } 98 }; 99 100 const uint8_t sha512_test_digests[][64] = { 101 { 102 // for test_msg0 103 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 104 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, 105 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, 106 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 107 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 108 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, 109 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, 110 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F 111 }, 112 { 113 // no test vector for test_msg1 114 }, 115 { 116 // for test_msg2 117 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 118 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, 119 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, 120 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, 121 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 122 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, 123 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, 124 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 125 } 126 }; 127 128 const uint8_t sha512_224_test_digests[][28] = { 129 { 130 // for test_msg0 131 0x46, 0x34, 0x27, 0x0F, 0x70, 0x7B, 0x6A, 0x54, 132 0xDA, 0xAE, 0x75, 0x30, 0x46, 0x08, 0x42, 0xE2, 133 0x0E, 0x37, 0xED, 0x26, 0x5C, 0xEE, 0xE9, 0xA4, 134 0x3E, 0x89, 0x24, 0xAA 135 }, 136 { 137 // no test vector for test_msg1 138 }, 139 { 140 // for test_msg2 141 0x23, 0xFE, 0xC5, 0xBB, 0x94, 0xD6, 0x0B, 0x23, 142 0x30, 0x81, 0x92, 0x64, 0x0B, 0x0C, 0x45, 0x33, 143 0x35, 0xD6, 0x64, 0x73, 0x4F, 0xE4, 0x0E, 0x72, 144 0x68, 0x67, 0x4A, 0xF9 145 } 146 }; 147 148 const uint8_t sha512_256_test_digests[][32] = { 149 { 150 // for test_msg0 151 0x53, 0x04, 0x8E, 0x26, 0x81, 0x94, 0x1E, 0xF9, 152 0x9B, 0x2E, 0x29, 0xB7, 0x6B, 0x4C, 0x7D, 0xAB, 153 0xE4, 0xC2, 0xD0, 0xC6, 0x34, 0xFC, 0x6D, 0x46, 154 0xE0, 0xE2, 0xF1, 0x31, 0x07, 0xE7, 0xAF, 0x23 155 }, 156 { 157 // no test vector for test_msg1 158 }, 159 { 160 // for test_msg2 161 0x39, 0x28, 0xE1, 0x84, 0xFB, 0x86, 0x90, 0xF8, 162 0x40, 0xDA, 0x39, 0x88, 0x12, 0x1D, 0x31, 0xBE, 163 0x65, 0xCB, 0x9D, 0x3E, 0xF8, 0x3E, 0xE6, 0x14, 164 0x6F, 0xEA, 0xC8, 0x61, 0xE1, 0x9B, 0x56, 0x3A 165 } 166 }; 167 168 /* 169 * Local reimplementation of cmn_err, since it's used in sha2.c. 170 */ 171 /*ARGSUSED*/ 172 void 173 cmn_err(int level, char *format, ...) 174 { 175 va_list ap; 176 va_start(ap, format); 177 vfprintf(stderr, format, ap); 178 va_end(ap); 179 } 180 181 int 182 main(int argc, char *argv[]) 183 { 184 boolean_t failed = B_FALSE; 185 uint64_t cpu_mhz = 0; 186 187 if (argc == 2) 188 cpu_mhz = atoi(argv[1]); 189 190 #define SHA2_ALGO_TEST(_m, mode, diglen, testdigest) \ 191 do { \ 192 SHA2_CTX ctx; \ 193 uint8_t digest[diglen / 8]; \ 194 SHA2Init(SHA ## mode ## _MECH_INFO_TYPE, &ctx); \ 195 SHA2Update(&ctx, _m, strlen(_m)); \ 196 SHA2Final(digest, &ctx); \ 197 printf("SHA%-9sMessage: " #_m "\tResult: ", #mode); \ 198 if (bcmp(digest, testdigest, diglen / 8) == 0) { \ 199 printf("OK\n"); \ 200 } else { \ 201 printf("FAILED!\n"); \ 202 failed = B_TRUE; \ 203 } \ 204 } while (0) 205 206 #define SHA2_PERF_TEST(mode, diglen) \ 207 do { \ 208 SHA2_CTX ctx; \ 209 uint8_t digest[diglen / 8]; \ 210 uint8_t block[131072]; \ 211 uint64_t delta; \ 212 double cpb = 0; \ 213 int i; \ 214 struct timeval start, end; \ 215 bzero(block, sizeof (block)); \ 216 gettimeofday(&start, NULL); \ 217 SHA2Init(SHA ## mode ## _MECH_INFO_TYPE, &ctx); \ 218 for (i = 0; i < 8192; i++) \ 219 SHA2Update(&ctx, block, sizeof (block)); \ 220 SHA2Final(digest, &ctx); \ 221 gettimeofday(&end, NULL); \ 222 delta = (end.tv_sec * 1000000llu + end.tv_usec) - \ 223 (start.tv_sec * 1000000llu + start.tv_usec); \ 224 if (cpu_mhz != 0) { \ 225 cpb = (cpu_mhz * 1e6 * ((double)delta / \ 226 1000000)) / (8192 * 128 * 1024); \ 227 } \ 228 printf("SHA%-9s%llu us (%.02f CPB)\n", #mode, delta, cpb);\ 229 } while (0) 230 231 printf("Running algorithm correctness tests:\n"); 232 SHA2_ALGO_TEST(test_msg0, 256, 256, sha256_test_digests[0]); 233 SHA2_ALGO_TEST(test_msg1, 256, 256, sha256_test_digests[1]); 234 SHA2_ALGO_TEST(test_msg0, 384, 384, sha384_test_digests[0]); 235 SHA2_ALGO_TEST(test_msg2, 384, 384, sha384_test_digests[2]); 236 SHA2_ALGO_TEST(test_msg0, 512, 512, sha512_test_digests[0]); 237 SHA2_ALGO_TEST(test_msg2, 512, 512, sha512_test_digests[2]); 238 SHA2_ALGO_TEST(test_msg0, 512_224, 224, sha512_224_test_digests[0]); 239 SHA2_ALGO_TEST(test_msg2, 512_224, 224, sha512_224_test_digests[2]); 240 SHA2_ALGO_TEST(test_msg0, 512_256, 256, sha512_256_test_digests[0]); 241 SHA2_ALGO_TEST(test_msg2, 512_256, 256, sha512_256_test_digests[2]); 242 243 if (failed) 244 return (1); 245 246 printf("Running performance tests (hashing 1024 MiB of data):\n"); 247 SHA2_PERF_TEST(256, 256); 248 SHA2_PERF_TEST(512, 512); 249 250 return (0); 251 }