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]
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include <sys/types.h>
30 #include <security/cryptoki.h>
31 #include <sys/crypto/common.h>
33 #include <cryptoutil.h>
34 #include "softGlobal.h"
35 #include "softSession.h"
36 #include "softObject.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.
46 soft_genDHkey_set_attribute(soft_object_t
*key
, CK_ATTRIBUTE_TYPE type
,
47 uchar_t
*buf
, uint32_t buflen
, boolean_t
public)
51 biginteger_t
*dst
= NULL
;
58 dst
= OBJ_PUB_DH_VALUE(key
);
60 dst
= OBJ_PRI_DH_VALUE(key
);
64 dst
= OBJ_PRI_DH_PRIME(key
);
68 dst
= OBJ_PRI_DH_BASE(key
);
72 if ((rv
= dup_bigint_attr(&src
, buf
, buflen
)) != CKR_OK
)
75 /* Copy the attribute in the key object. */
76 copy_bigint_attr(&src
, dst
);
79 /* No need to free big_value because dst holds it now after copy. */
85 * This function covers the DH Key agreement.
88 soft_dh_genkey_pair(soft_object_t
*pubkey
, soft_object_t
*prikey
)
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
);
97 uchar_t private_x
[MAX_KEY_ATTR_BUFLEN
];
98 uchar_t public_y
[MAX_KEY_ATTR_BUFLEN
];
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
),
120 free(template.pValue
);
126 value_bits
= (uint32_t)(*((CK_ULONG
*)(template.pValue
)));
127 #else /* !__sparcv9 */
128 value_bits
= *((CK_ULONG
*)(template.pValue
));
129 #endif /* __sparcv9 */
131 free(template.pValue
);
134 * The input to the first phase shall be the Diffie-Hellman
135 * parameters, which include prime, base, and private-value length.
137 rv
= soft_get_public_value(pubkey
, CKA_PRIME
, prime
, &prime_len
);
142 rv
= soft_get_public_value(pubkey
, CKA_BASE
, base
, &base_len
);
147 /* Inputs to DH key pair generation. */
149 k
.prime_bits
= CRYPTO_BYTES2BITS(prime_len
);
151 k
.base_bytes
= base_len
;
152 k
.value_bits
= value_bits
;
153 k
.rfunc
= (IS_TOKEN_OBJECT(pubkey
) || IS_TOKEN_OBJECT(prikey
)) ?
154 pkcs11_get_random
: pkcs11_get_urandom
;
156 /* Outputs from DH key pair generation. */
157 k
.private_x
= private_x
;
158 k
.public_y
= public_y
;
160 /* If value_bits is 0, it will return as same size as prime */
161 if ((rv
= dh_genkey_pair(&k
)) != CKR_OK
) {
166 * The integer public value y shall be converted to an octet
167 * string PV of length k, the public value.
169 if ((rv
= soft_genDHkey_set_attribute(pubkey
, CKA_VALUE
, public_y
,
170 prime_len
, B_TRUE
)) != CKR_OK
) {
174 /* Convert the big integer private value to an octet string. */
175 if ((rv
= soft_genDHkey_set_attribute(prikey
, CKA_VALUE
, private_x
,
176 CRYPTO_BITS2BYTES(k
.value_bits
), B_FALSE
)) != CKR_OK
) {
180 /* Convert the big integer prime to an octet string. */
181 if ((rv
= soft_genDHkey_set_attribute(prikey
, CKA_PRIME
, prime
,
182 CRYPTO_BITS2BYTES(k
.prime_bits
), B_FALSE
)) != CKR_OK
) {
186 /* Convert the big integer base to an octet string. */
187 if ((rv
= soft_genDHkey_set_attribute(prikey
, CKA_BASE
, base
,
188 k
.base_bytes
, B_FALSE
)) != CKR_OK
) {
192 /* Update private-value length in bits; could have been 0 before */
193 OBJ_PRI_DH_VAL_BITS(prikey
) = k
.value_bits
;
201 soft_dh_key_derive(soft_object_t
*basekey
, soft_object_t
*secretkey
,
202 void *publicvalue
, size_t publicvaluelen
)
205 uchar_t privatevalue
[MAX_KEY_ATTR_BUFLEN
];
206 uint32_t privatevaluelen
= sizeof (privatevalue
);
207 uchar_t privateprime
[MAX_KEY_ATTR_BUFLEN
];
208 uint32_t privateprimelen
= sizeof (privateprime
);
209 uchar_t key
[MAX_KEY_ATTR_BUFLEN
];
213 rv
= soft_get_private_value(basekey
, CKA_VALUE
, privatevalue
,
219 rv
= soft_get_private_value(basekey
, CKA_PRIME
, privateprime
,
225 /* keylen may be 0 if CKA_VALUE_LEN did not specify */
226 keylen
= OBJ_SEC_VALUE_LEN(secretkey
);
227 if (keylen
> sizeof (key
)) { /* check for overflow */
228 rv
= CKR_ATTRIBUTE_VALUE_INVALID
;
232 k
.prime
= privateprime
;
233 k
.prime_bits
= CRYPTO_BYTES2BITS(privateprimelen
);
234 k
.value_bits
= CRYPTO_BYTES2BITS(privatevaluelen
);
235 k
.private_x
= privatevalue
;
236 k
.public_y
= publicvalue
;
239 /* keylen may be modified if it was 0 or conflicts with key type */
240 rv
= dh_key_derive(&k
, secretkey
->key_type
, key
, &keylen
, 0);
246 if ((OBJ_SEC_VALUE(secretkey
) = malloc(keylen
)) == NULL
) {
247 rv
= CKR_HOST_MEMORY
;
251 OBJ_SEC_VALUE_LEN(secretkey
) = keylen
;
252 (void) memcpy(OBJ_SEC_VALUE(secretkey
), key
, keylen
);