2 * Copyright (c) 2000-2001,2011-2012,2014 Apple 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 * FEESignatureObject.cpp - implementations of FEE-style raw sign/verify classes
24 #ifdef CRYPTKIT_CSP_ENABLE
26 #include "FEESignatureObject.h"
27 #include <security_cryptkit/feePublicKey.h>
28 #include <security_cryptkit/feeDigitalSignature.h>
29 #include <security_cryptkit/falloc.h>
31 #include <security_utilities/simulatecrash_assert.h>
32 #include <security_utilities/debugging.h>
34 #define feeSigObjDebug(args...) secinfo("feeSig", ##args)
36 CryptKit::FEESigner::~FEESigner()
38 if(mWeMallocdFeeKey
) {
39 assert(mFeeKey
!= NULL
);
40 feePubKeyFree(mFeeKey
);
45 * padding from context
47 void CryptKit::FEESigner::sigFormatFromContext(
48 const Context
&context
)
50 CSSM_PADDING padding
= context
.getInt(CSSM_ATTRIBUTE_PADDING
);
52 case CSSM_PADDING_SIGRAW
:
60 * obtain key from context, validate, convert to native FEE key
62 void CryptKit::FEESigner::keyFromContext(
63 const Context
&context
)
65 if(initFlag() && (mFeeKey
!= NULL
)) {
66 /* reusing context, OK */
70 CSSM_KEYCLASS keyClass
;
73 /* signing with private key */
74 keyClass
= CSSM_KEYCLASS_PRIVATE_KEY
;
75 keyUse
= CSSM_KEYUSE_SIGN
;
78 /* verifying with public key */
79 keyClass
= CSSM_KEYCLASS_PUBLIC_KEY
;
80 keyUse
= CSSM_KEYUSE_VERIFY
;
83 mFeeKey
= contextToFeeKey(context
,
93 void CryptKit::FEESigner::signerInit(
94 const Context
&context
,
97 setIsSigning(isSigning
);
98 keyFromContext(context
);
99 sigFormatFromContext(context
);
104 * Note that, unlike the implementation in security_cryptkit/feePublicKey.c, we ignore
105 * the Pm which used to be used as salt for the digest. That made staged verification
106 * impossible and I do not believe it increased security.
108 void CryptKit::FEERawSigner::sign(
112 size_t *sigLen
) /* IN/OUT */
116 unsigned char *feeSig
= NULL
;
117 unsigned feeSigLen
=0;
119 if(mFeeKey
== NULL
) {
120 throwCryptKit(FR_BadPubKey
, "FEERawSigner::sign (no key)");
122 fsig
= feeSigNewWithKey(mFeeKey
, mRandFcn
, mRandRef
);
124 throwCryptKit(FR_BadPubKey
, "FEERawSigner::sign");
126 frtn
= feeSigSign(fsig
,
127 (unsigned char *)data
,
130 if(frtn
== FR_Success
) {
131 frtn
= feeSigData(fsig
, &feeSig
, &feeSigLen
);
135 throwCryptKit(frtn
, "FEERawSigner::sign");
138 /* copy out to caller and ffree */
139 if(*sigLen
< feeSigLen
) {
140 feeSigObjDebug("FEERawSigner sign overflow\n");
142 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
144 memmove(sig
, feeSig
, feeSigLen
);
149 void CryptKit::FEERawSigner::verify(
158 if(mFeeKey
== NULL
) {
159 throwCryptKit(FR_BadPubKey
, "FEERawSigner::verify (no key)");
161 frtn
= feeSigParse((unsigned char *)sig
, sigLen
, &fsig
);
163 throwCryptKit(frtn
, "feeSigParse");
165 frtn
= feeSigVerify(fsig
,
166 (unsigned char *)data
,
167 (unsigned int)dataLen
,
171 throwCryptKit(frtn
, NULL
);
175 size_t CryptKit::FEERawSigner::maxSigSize()
180 frtn
= feeSigSize(mFeeKey
, &rtn
);
182 throwCryptKit(frtn
, "feeSigSize");
187 /* ECDSA - this is really easy. */
189 void CryptKit::FEEECDSASigner::sign(
193 size_t *sigLen
) /* IN/OUT */
195 unsigned char *feeSig
;
199 if(mFeeKey
== NULL
) {
200 throwCryptKit(FR_BadPubKey
, "FEERawSigner::sign (no key)");
202 frtn
= feeECDSASign(mFeeKey
,
204 (unsigned char *)data
, // data to be signed
205 (unsigned int)dataLen
, // in bytes
211 throwCryptKit(frtn
, "feeECDSASign");
213 /* copy out to caller and ffree */
214 if(*sigLen
< feeSigLen
) {
215 feeSigObjDebug("feeECDSASign overflow\n");
217 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR
);
219 memmove(sig
, feeSig
, feeSigLen
);
225 void CryptKit::FEEECDSASigner::verify(
233 if(mFeeKey
== NULL
) {
234 throwCryptKit(FR_BadPubKey
, "FEERawSigner::verify (no key)");
236 frtn
= feeECDSAVerify(
237 (unsigned char *)sig
,
239 (unsigned char *)data
,
240 (unsigned int)dataLen
,
244 throwCryptKit(frtn
, NULL
);
248 size_t CryptKit::FEEECDSASigner::maxSigSize()
253 frtn
= feeECDSASigSize(mFeeKey
, &rtn
);
255 throwCryptKit(frtn
, "feeECDSASigSize");
260 #endif /* CRYPTKIT_CSP_ENABLE */