1 /* $NetBSD: sha1.c,v 1.1.1.4 2014/12/10 03:34:28 christos Exp $ */ 2 3 /* 4 * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Portions copyright (c) 2008 Nominet UK. All rights reserved. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the above copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 32 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 34 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 35 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 */ 42 43 /* Id */ 44 45 /* sha1 [-m module] [-s $slot] [-n count] */ 46 47 /*! \file */ 48 49 #include <config.h> 50 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <string.h> 54 #include <time.h> 55 #include <unistd.h> 56 57 #include <isc/commandline.h> 58 #include <isc/result.h> 59 #include <isc/types.h> 60 61 #include <pk11/pk11.h> 62 #include <pk11/result.h> 63 64 #ifndef HAVE_CLOCK_GETTIME 65 #ifndef CLOCK_REALTIME 66 #define CLOCK_REALTIME 0 67 #endif 68 69 int 70 clock_gettime(int32_t id, struct timespec *tp) 71 { 72 struct timeval tv; 73 int result; 74 75 result = gettimeofday(&tv, NULL); 76 if (result) 77 return (result); 78 tp->tv_sec = tv.tv_sec; 79 tp->tv_nsec = (long) tv.tv_usec * 1000; 80 return (result); 81 } 82 #endif 83 84 CK_BYTE buf[1024]; 85 86 int 87 main(int argc, char *argv[]) { 88 isc_result_t result; 89 CK_RV rv; 90 CK_SLOT_ID slot = 0; 91 CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; 92 CK_MECHANISM mech = { CKM_SHA_1, NULL, 0 }; 93 CK_ULONG len = sizeof(buf); 94 pk11_context_t pctx; 95 pk11_optype_t op_type = OP_DIGEST; 96 char *lib_name = NULL; 97 int error = 0; 98 int c, errflg = 0; 99 unsigned int count = 1000; 100 unsigned int i; 101 struct timespec starttime; 102 struct timespec endtime; 103 104 while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) { 105 switch (c) { 106 case 'm': 107 lib_name = isc_commandline_argument; 108 break; 109 case 's': 110 slot = atoi(isc_commandline_argument); 111 op_type = OP_ANY; 112 break; 113 case 'n': 114 count = atoi(isc_commandline_argument); 115 break; 116 case ':': 117 fprintf(stderr, 118 "Option -%c requires an operand\n", 119 isc_commandline_option); 120 errflg++; 121 break; 122 case '?': 123 default: 124 fprintf(stderr, "Unrecognised option: -%c\n", 125 isc_commandline_option); 126 errflg++; 127 } 128 } 129 130 if (errflg) { 131 fprintf(stderr, "Usage:\n"); 132 fprintf(stderr, 133 "\tssha1 [-m module] [-s slot] [-n count]\n"); 134 exit(1); 135 } 136 137 pk11_result_register(); 138 139 /* Initialize the CRYPTOKI library */ 140 if (lib_name != NULL) 141 pk11_set_lib_name(lib_name); 142 143 result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, 144 ISC_FALSE, NULL, slot); 145 if ((result != ISC_R_SUCCESS) && 146 (result != PK11_R_NORANDOMSERVICE) && 147 (result != PK11_R_NOAESSERVICE)) { 148 fprintf(stderr, "Error initializing PKCS#11: %s\n", 149 isc_result_totext(result)); 150 exit(1); 151 } 152 153 hSession = pctx.session; 154 155 /* Randomize the buffer */ 156 rv = pkcs_C_GenerateRandom(hSession, buf, len); 157 if (rv != CKR_OK) { 158 fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); 159 goto exit_session; 160 } 161 162 if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { 163 perror("clock_gettime(start)"); 164 goto exit_session; 165 } 166 167 /* Initialize Digest */ 168 rv = pkcs_C_DigestInit(hSession, &mech); 169 if (rv != CKR_OK) { 170 fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv); 171 goto exit_session; 172 } 173 174 175 for (i = 0; i < count; i++) { 176 /* Digest buffer */ 177 rv = pkcs_C_DigestUpdate(hSession, buf, len); 178 if (rv != CKR_OK) { 179 fprintf(stderr, 180 "C_DigestUpdate[%u]: Error = 0x%.8lX\n", 181 i, rv); 182 error = 1; 183 break; 184 } 185 } 186 187 /* Finalize Digest (unconditionally) */ 188 len = 20U; 189 rv = pkcs_C_DigestFinal(hSession, buf, &len); 190 if ((rv != CKR_OK) && !error) 191 fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv); 192 193 if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { 194 perror("clock_gettime(end)"); 195 goto exit_session; 196 } 197 198 endtime.tv_sec -= starttime.tv_sec; 199 endtime.tv_nsec -= starttime.tv_nsec; 200 while (endtime.tv_nsec < 0) { 201 endtime.tv_sec -= 1; 202 endtime.tv_nsec += 1000000000; 203 } 204 printf("%uK digested bytes in %ld.%09lds\n", i, 205 endtime.tv_sec, endtime.tv_nsec); 206 if (i > 0) 207 printf("%g digested bytes/s\n", 208 1024 * i / ((double) endtime.tv_sec + 209 (double) endtime.tv_nsec / 1000000000.)); 210 211 exit_session: 212 pk11_return_session(&pctx); 213 (void) pk11_finalize(); 214 215 exit(error); 216 } 217