ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
99bbb58ce7c172798fecb21d2d12756c159cff14Tinderbox User * Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * Portions copyright (c) 2008 Nominet UK. All rights reserved.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * Redistribution and use in source and binary forms, with or without
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * modification, are permitted provided that the following conditions
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * are met:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * 1. Redistributions of source code must retain the above copyright
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * notice, this list of conditions and the following disclaimer.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * 2. Redistributions in binary form must reproduce the above copyright
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * notice, this list of conditions and the following disclaimer in the
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * documentation and/or other materials provided with the distribution.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt *
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/* $Id$ */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/* random [-m module] [-s $slot] [-n count] */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt/*! \file */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <config.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <stdio.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <stdlib.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <string.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <time.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <unistd.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/commandline.h>
3759f10fc543747668b1ca4b4671f35b0dea8445Francis Dupont#include <isc/print.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/result.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#include <isc/types.h>
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt#include <isc/util.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt#include <pk11/pk11.h>
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt#include <pk11/result.h>
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#ifndef HAVE_CLOCK_GETTIME
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt#include <sys/time.h>
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#ifndef CLOCK_REALTIME
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#define CLOCK_REALTIME 0
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Huntstatic int clock_gettime(int32_t id, struct timespec *tp);
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Huntstatic int
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntclock_gettime(int32_t id, struct timespec *tp)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt{
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt struct timeval tv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt UNUSED(id);
699f790c49d03a9ef3c3234a72d272bb469203e8Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt result = gettimeofday(&tv, NULL);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (result)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt tp->tv_sec = tv.tv_sec;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt tp->tv_nsec = (long) tv.tv_usec * 1000;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt return (result);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt#endif
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan HuntCK_BYTE buf[1024];
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntint
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Huntmain(int argc, char *argv[]) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_t result;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_RV rv;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_SLOT_ID slot = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt CK_ULONG len = sizeof(buf);
dbb012765c735ee0d82dedb116cdc7cf18957814Evan Hunt pk11_context_t pctx;
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt pk11_optype_t op_type = OP_RAND;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt char *lib_name = NULL;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int error = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt int c, errflg = 0;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int count = 1000;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt unsigned int i;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt struct timespec starttime;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt struct timespec endtime;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt switch (c) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case 'm':
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt lib_name = isc_commandline_argument;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case 's':
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt slot = atoi(isc_commandline_argument);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt op_type = OP_ANY;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case 'n':
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt count = atoi(isc_commandline_argument);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case ':':
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fprintf(stderr,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt "Option -%c requires an operand\n",
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_commandline_option);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt errflg++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt case '?':
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt default:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fprintf(stderr, "Unrecognised option: -%c\n",
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_commandline_option);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt errflg++;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (errflg) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fprintf(stderr, "Usage:\n");
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fprintf(stderr,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt "\trandom [-m module] [-s slot] [-n count]\n");
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exit(1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt pk11_result_register();
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* Initialize the CRYPTOKI library */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (lib_name != NULL)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_set_lib_name(lib_name);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE,
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt ISC_FALSE, NULL, slot);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt if ((result != ISC_R_SUCCESS) &&
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt (result != PK11_R_NODIGESTSERVICE) &&
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt (result != PK11_R_NOAESSERVICE)) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fprintf(stderr, "Error initializing PKCS#11: %s\n",
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt isc_result_totext(result));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exit(1);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt hSession = pctx.session;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt perror("clock_gettime(start)");
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto exit_session;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt for (i = 0; i < count; i++) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt /* Get random bytes */
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt rv = pkcs_C_GenerateRandom(hSession, buf, len);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (rv != CKR_OK) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt fprintf(stderr,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt "C_GenerateRandom[%u]: Error = 0x%.8lX\n",
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt i, rv);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt error = 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt break;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt perror("clock_gettime(end)");
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt goto exit_session;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt endtime.tv_sec -= starttime.tv_sec;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt endtime.tv_nsec -= starttime.tv_nsec;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt while (endtime.tv_nsec < 0) {
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt endtime.tv_sec -= 1;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt endtime.tv_nsec += 1000000000;
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt }
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt printf("%uK random bytes in %ld.%09lds\n", i,
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt endtime.tv_sec, endtime.tv_nsec);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt if (i > 0)
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt printf("%g random bytes/s\n",
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt 1024 * i / ((double) endtime.tv_sec +
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt (double) endtime.tv_nsec / 1000000000.));
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exit_session:
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt pk11_return_session(&pctx);
acbb301e648b82fcc38b876a44403cf0fe539cc9Evan Hunt (void) pk11_finalize();
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt exit(error);
ba751492fcc4f161a18b983d4f018a1a52938cb9Evan Hunt}