dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softDH.c
blob42584003202277ab444e0328530d52d1245c0729
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <stdlib.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <sys/types.h>
30 #include <security/cryptoki.h>
31 #include <sys/crypto/common.h>
32 #include <des_impl.h>
33 #include <cryptoutil.h>
34 #include "softGlobal.h"
35 #include "softSession.h"
36 #include "softObject.h"
37 #include "softDH.h"
38 #include "softCrypt.h"
42 * This function takes a converted big integer of the specified attribute
43 * as an octet string and stores it in the corresponding key object.
45 static CK_RV
46 soft_genDHkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
47 uchar_t *buf, uint32_t buflen, boolean_t public)
50 CK_RV rv = CKR_OK;
51 biginteger_t *dst = NULL;
52 biginteger_t src;
54 switch (type) {
56 case CKA_VALUE:
57 if (public)
58 dst = OBJ_PUB_DH_VALUE(key);
59 else
60 dst = OBJ_PRI_DH_VALUE(key);
61 break;
63 case CKA_PRIME:
64 dst = OBJ_PRI_DH_PRIME(key);
65 break;
67 case CKA_BASE:
68 dst = OBJ_PRI_DH_BASE(key);
69 break;
72 if ((rv = dup_bigint_attr(&src, buf, buflen)) != CKR_OK)
73 goto cleanexit;
75 /* Copy the attribute in the key object. */
76 copy_bigint_attr(&src, dst);
78 cleanexit:
79 /* No need to free big_value because dst holds it now after copy. */
80 return (rv);
85 * This function covers the DH Key agreement.
87 CK_RV
88 soft_dh_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
90 CK_RV rv;
91 CK_ATTRIBUTE template;
92 uchar_t prime[MAX_KEY_ATTR_BUFLEN];
93 uint32_t prime_len = sizeof (prime);
94 uchar_t base[MAX_KEY_ATTR_BUFLEN];
95 uint32_t base_len = sizeof (base);
96 uint32_t value_bits;
97 uchar_t private_x[MAX_KEY_ATTR_BUFLEN];
98 uchar_t public_y[MAX_KEY_ATTR_BUFLEN];
99 DHbytekey k;
101 if ((pubkey->class != CKO_PUBLIC_KEY) ||
102 (pubkey->key_type != CKK_DH)) {
103 return (CKR_KEY_TYPE_INCONSISTENT);
106 if ((prikey->class != CKO_PRIVATE_KEY) ||
107 (prikey->key_type != CKK_DH)) {
108 return (CKR_KEY_TYPE_INCONSISTENT);
111 /* Get private-value length in bits */
112 template.pValue = malloc(sizeof (CK_ULONG));
113 if (template.pValue == NULL) {
114 return (CKR_HOST_MEMORY);
116 template.ulValueLen = sizeof (CK_ULONG);
117 rv = get_ulong_attr_from_object(OBJ_PRI_DH_VAL_BITS(prikey),
118 &template);
119 if (rv != CKR_OK) {
120 free(template.pValue);
121 return (rv);
124 value_bits = *((CK_ULONG *)(template.pValue));
126 free(template.pValue);
129 * The input to the first phase shall be the Diffie-Hellman
130 * parameters, which include prime, base, and private-value length.
132 rv = soft_get_public_value(pubkey, CKA_PRIME, prime, &prime_len);
133 if (rv != CKR_OK) {
134 return (rv);
137 rv = soft_get_public_value(pubkey, CKA_BASE, base, &base_len);
138 if (rv != CKR_OK) {
139 goto ret;
142 /* Inputs to DH key pair generation. */
143 k.prime = prime;
144 k.prime_bits = CRYPTO_BYTES2BITS(prime_len);
145 k.base = base;
146 k.base_bytes = base_len;
147 k.value_bits = value_bits;
148 k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
149 pkcs11_get_random : pkcs11_get_urandom;
151 /* Outputs from DH key pair generation. */
152 k.private_x = private_x;
153 k.public_y = public_y;
155 /* If value_bits is 0, it will return as same size as prime */
156 if ((rv = dh_genkey_pair(&k)) != CKR_OK) {
157 goto ret;
161 * The integer public value y shall be converted to an octet
162 * string PV of length k, the public value.
164 if ((rv = soft_genDHkey_set_attribute(pubkey, CKA_VALUE, public_y,
165 prime_len, B_TRUE)) != CKR_OK) {
166 goto ret;
169 /* Convert the big integer private value to an octet string. */
170 if ((rv = soft_genDHkey_set_attribute(prikey, CKA_VALUE, private_x,
171 CRYPTO_BITS2BYTES(k.value_bits), B_FALSE)) != CKR_OK) {
172 goto ret;
175 /* Convert the big integer prime to an octet string. */
176 if ((rv = soft_genDHkey_set_attribute(prikey, CKA_PRIME, prime,
177 CRYPTO_BITS2BYTES(k.prime_bits), B_FALSE)) != CKR_OK) {
178 goto ret;
181 /* Convert the big integer base to an octet string. */
182 if ((rv = soft_genDHkey_set_attribute(prikey, CKA_BASE, base,
183 k.base_bytes, B_FALSE)) != CKR_OK) {
184 goto ret;
187 /* Update private-value length in bits; could have been 0 before */
188 OBJ_PRI_DH_VAL_BITS(prikey) = k.value_bits;
190 ret:
191 return (rv);
194 /* ARGSUSED3 */
195 CK_RV
196 soft_dh_key_derive(soft_object_t *basekey, soft_object_t *secretkey,
197 void *publicvalue, size_t publicvaluelen)
199 CK_RV rv;
200 uchar_t privatevalue[MAX_KEY_ATTR_BUFLEN];
201 uint32_t privatevaluelen = sizeof (privatevalue);
202 uchar_t privateprime[MAX_KEY_ATTR_BUFLEN];
203 uint32_t privateprimelen = sizeof (privateprime);
204 uchar_t key[MAX_KEY_ATTR_BUFLEN];
205 uint32_t keylen;
206 DHbytekey k;
208 rv = soft_get_private_value(basekey, CKA_VALUE, privatevalue,
209 &privatevaluelen);
210 if (rv != CKR_OK) {
211 return (rv);
214 rv = soft_get_private_value(basekey, CKA_PRIME, privateprime,
215 &privateprimelen);
216 if (rv != CKR_OK) {
217 goto ret;
220 /* keylen may be 0 if CKA_VALUE_LEN did not specify */
221 keylen = OBJ_SEC_VALUE_LEN(secretkey);
222 if (keylen > sizeof (key)) { /* check for overflow */
223 rv = CKR_ATTRIBUTE_VALUE_INVALID;
224 goto ret;
227 k.prime = privateprime;
228 k.prime_bits = CRYPTO_BYTES2BITS(privateprimelen);
229 k.value_bits = CRYPTO_BYTES2BITS(privatevaluelen);
230 k.private_x = privatevalue;
231 k.public_y = publicvalue;
232 k.rfunc = NULL;
234 /* keylen may be modified if it was 0 or conflicts with key type */
235 rv = dh_key_derive(&k, secretkey->key_type, key, &keylen, 0);
237 if (rv != CKR_OK) {
238 goto ret;
241 if ((OBJ_SEC_VALUE(secretkey) = malloc(keylen)) == NULL) {
242 rv = CKR_HOST_MEMORY;
243 goto ret;
246 OBJ_SEC_VALUE_LEN(secretkey) = keylen;
247 (void) memcpy(OBJ_SEC_VALUE(secretkey), key, keylen);
249 ret:
250 return (rv);