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>
25 #include <Security/utilities.h>
29 #include <open_ssl/opensslUtils/opensslUtils.h>
32 const Context
&context
,
33 const CssmData
&Param
, // other's public key. may be empty
34 CSSM_DATA
*keyData
, // mallocd by caller
35 // we fill in keyData->Length bytes
36 AppleCSPSession
&session
)
41 /* private DH key from context - required */
42 DH
*privKey
= contextToDhKey(context
, session
, CSSM_ATTRIBUTE_KEY
,
43 CSSM_KEYCLASS_PRIVATE_KEY
, CSSM_KEYUSE_DERIVE
, mallocdPrivKey
);
45 CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_KEY
);
47 cspDhDebug("DeriveKey_DH, privKey %p", privKey
);
48 privSize
= DH_size(privKey
);
49 if(privSize
< keyData
->Length
) {
50 /* we've been asked for more bits than this key can generate */
51 CssmError::throwMe(CSSMERR_CSP_UNSUPPORTED_KEY_SIZE
);
55 * Public key ("their" key) can come from two places:
56 * -- in the context as a CSSM_ATTRIBUTE_PUBLIC_KEY. THis is how
57 * public keys in X509 for must be used in this function
58 * -- in the incoming Param, the raw unformatted (PKCS3) form
60 bool mallocdPubKey
= false;
61 BIGNUM
*pubKeyBn
= NULL
;
62 bool allocdPubKeyBn
= false;
63 DH
*pubKey
= contextToDhKey(context
, session
, CSSM_ATTRIBUTE_PUBLIC_KEY
,
64 CSSM_KEYCLASS_PUBLIC_KEY
, CSSM_KEYUSE_DERIVE
, mallocdPubKey
);
66 if(pubKey
->pub_key
== NULL
) {
67 errorLog0("DeriveKey_DH: public key in context with no pub_key\n");
68 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
70 pubKeyBn
= pubKey
->pub_key
;
71 cspDhDebug("DeriveKey_DH, pubKey from context %p", pubKey
);
74 if((Param
.Data
== NULL
) || (Param
.Length
== 0)) {
75 errorLog0("DeriveKey_DH: no pub_key, no Param\n");
76 CssmError::throwMe(CSSMERR_CSP_INVALID_KEY
);
78 pubKeyBn
= BN_bin2bn(Param
.Data
, Param
.Length
, NULL
);
79 if(pubKeyBn
== NULL
) {
80 CssmError::throwMe(CSSMERR_CSP_MEMORY_ERROR
);
82 allocdPubKeyBn
= true;
83 cspDhDebug("DeriveKey_DH, no pubKey in context");
85 unsigned char *buf
= (unsigned char *)session
.malloc(privSize
);
86 int rtn
= DH_compute_key(buf
, pubKeyBn
, privKey
);
89 * FIXME : I have not found a specification describing *which*
90 * bytes of the value we just computed we are supposed to
91 * use as the actual key bytes. We use the M.S. bytes.
93 * Note that due to modulo arithmetic, we may have gotten fewer
94 * bytes than we asked for. If so, the caller will have
95 * to deal with that if they really need privSize bytes.
97 assert((uint32
)rtn
<= privSize
);
98 uint32 toMove
= keyData
->Length
;
99 if((uint32
)rtn
< toMove
) {
100 toMove
= (uint32
)rtn
;
102 memmove(keyData
->Data
, buf
, toMove
);
103 keyData
->Length
= toMove
;
116 throwRsaDsa("DH_compute_key");