2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 * DH_exchange.cp - Diffie-Hellman key exchange
23 #include "DH_exchange.h"
24 #include <Security/cssmerr.h>
28 #include <opensslUtils/opensslUtils.h>
31 const Context
&context
,
32 const CssmData
&Param
, // other's public key. may be empty
33 CSSM_DATA
*keyData
, // mallocd by caller
34 // we fill in keyData->Length bytes
35 AppleCSPSession
&session
)
40 /* private DH key from context - required */
41 DH
*privKey
= contextToDhKey(context
, session
, CSSM_ATTRIBUTE_KEY
,
42 CSSM_KEYCLASS_PRIVATE_KEY
, CSSM_KEYUSE_DERIVE
, mallocdPrivKey
);
44 CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY
);
46 cspDhDebug("DeriveKey_DH, privKey %p", privKey
);
47 privSize
= DH_size(privKey
);
48 if(privSize
< keyData
->Length
) {
49 /* we've been asked for more bits than this key can generate */
50 CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE
);
54 * Public key ("their" key) can come from two places:
55 * -- in the context as a CSSM_ATTRIBUTE_PUBLIC_KEY. This is how
56 * public keys in X509 format must be used in this function
57 * -- in the incoming Param, the raw unformatted (PKCS3) form
59 bool mallocdPubKey
= false;
60 BIGNUM
*pubKeyBn
= NULL
;
61 bool allocdPubKeyBn
= false;
62 DH
*pubKey
= contextToDhKey(context
, session
, CSSM_ATTRIBUTE_PUBLIC_KEY
,
63 CSSM_KEYCLASS_PUBLIC_KEY
, CSSM_KEYUSE_DERIVE
, mallocdPubKey
);
65 if(pubKey
->pub_key
== NULL
) {
66 errorLog0("DeriveKey_DH: public key in context with no pub_key\n");
67 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
69 pubKeyBn
= pubKey
->pub_key
;
70 cspDhDebug("DeriveKey_DH, pubKey from context %p", pubKey
);
73 if((Param
.Data
== NULL
) || (Param
.Length
== 0)) {
74 errorLog0("DeriveKey_DH: no pub_key, no Param\n");
75 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
77 pubKeyBn
= BN_bin2bn(Param
.Data
, (int)Param
.Length
, NULL
);
78 if(pubKeyBn
== NULL
) {
79 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
81 allocdPubKeyBn
= true;
82 cspDhDebug("DeriveKey_DH, no pubKey in context");
84 unsigned char *buf
= (unsigned char *)session
.malloc(privSize
);
85 int rtn
= DH_compute_key(buf
, pubKeyBn
, privKey
);
88 * FIXME : I have not found a specification describing *which*
89 * bytes of the value we just computed we are supposed to
90 * use as the actual key bytes. We use the M.S. bytes.
92 * Note that due to modulo arithmetic, we may have gotten fewer
93 * bytes than we asked for. If so, the caller will have
94 * to deal with that if they really need privSize bytes.
96 assert((uint32
)rtn
<= privSize
);
97 CSSM_SIZE toMove
= keyData
->Length
;
98 if((uint32
)rtn
< toMove
) {
101 memmove(keyData
->Data
, buf
, toMove
);
102 keyData
->Length
= toMove
;
115 throwRsaDsa("DH_compute_key");