Home | History | Annotate | Download | only in common
      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://www.opensolaris.org/os/licensing.
     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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /*
     27  * Random Number Generation Functions
     28  * (as defined in PKCS#11 spec section 11.15)
     29  *
     30  */
     31 
     32 #include <sys/types.h>
     33 #include <sys/stat.h>
     34 #include <fcntl.h>
     35 #include <errno.h>
     36 #include <string.h>
     37 
     38 #include "metaGlobal.h"
     39 
     40 /*
     41  * meta_SeedRandom
     42  *
     43  * Unlike most other metaslot functions, meta_SeedRandom does not distribute
     44  * the call to a specific provider. Rather, we assume that the /dev/urandom
     45  * implementation is a kCF consumer, and is pulling randomness from everywhere
     46  * it can. Thus, by seeding /dev/urandom we let kCF potentially do all the
     47  * work.
     48  *
     49  * NOTES:
     50  * 1) /dev/urandom vs. /dev/random... Unfortunately P11 does not allow app
     51  *    to request a "quality", so we'll just assume urandom is good enough.
     52  *    Concerned apps can pull hardcore randomness from specific places they
     53  *    trust (eg by checking for CKF_HW?)..
     54  *
     55  */
     56 CK_RV
     57 meta_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed,
     58     CK_ULONG ulSeedLen)
     59 {
     60 	CK_RV rv;
     61 	meta_session_t *session;
     62 
     63 	if (pSeed == NULL || ulSeedLen == 0)
     64 		return (CKR_ARGUMENTS_BAD);
     65 
     66 	/* Just check handle for validity, we don't need it for anything. */
     67 	rv = meta_handle2session(hSession, &session);
     68 	if (rv != CKR_OK)
     69 		return (rv);
     70 	REFRELEASE(session);
     71 
     72 	if (pkcs11_seed_urandom(pSeed, ulSeedLen) < 0) {
     73 		if (errno == EACCES)
     74 			return (CKR_RANDOM_SEED_NOT_SUPPORTED);
     75 		return (CKR_DEVICE_ERROR);
     76 	}
     77 	return (CKR_OK);
     78 }
     79 
     80 /*
     81  * meta_GenerateRandom
     82  *
     83  * Unlike most other metaslot functions, meta_GenerateRandom does not distribute
     84  * the call to a specific provider. Rather, we assume that the /dev/urandom
     85  * implementation is a kCF consumer, and is pulling randomness from everywhere
     86  * it can. Thus, by reading /dev/urandom we let kCF potentially do all the
     87  * work.
     88  *
     89  */
     90 CK_RV
     91 meta_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
     92     CK_ULONG ulRandomLen)
     93 {
     94 	CK_RV rv;
     95 	meta_session_t *session;
     96 
     97 	if (pRandomData == NULL || ulRandomLen < 1)
     98 		return (CKR_ARGUMENTS_BAD);
     99 
    100 	/* Just check handle for validity, we don't need it for anything. */
    101 	rv = meta_handle2session(hSession, &session);
    102 	if (rv != CKR_OK)
    103 		return (rv);
    104 	REFRELEASE(session);
    105 
    106 	if (pkcs11_get_urandom(pRandomData, ulRandomLen) < 0) {
    107 		return (CKR_DEVICE_ERROR);
    108 	}
    109 	return (CKR_OK);
    110 }
    111