]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_apple_csp/lib/FEESignatureObject.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / Security / libsecurity_apple_csp / lib / FEESignatureObject.cpp
1 /*
2 * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 /*
20 * FEESignatureObject.cpp - implementations of FEE-style raw sign/verify classes
21 *
22 */
23
24 #ifdef CRYPTKIT_CSP_ENABLE
25
26 #include "FEESignatureObject.h"
27 #include <security_cryptkit/feePublicKey.h>
28 #include <security_cryptkit/feeDigitalSignature.h>
29 #include <security_cryptkit/falloc.h>
30 #include <stdexcept>
31 #include <assert.h>
32 #include <security_utilities/debugging.h>
33
34 #define feeSigObjDebug(args...) secdebug("feeSig", ##args)
35
36 CryptKit::FEESigner::~FEESigner()
37 {
38 if(mWeMallocdFeeKey) {
39 assert(mFeeKey != NULL);
40 feePubKeyFree(mFeeKey);
41 }
42 }
43
44 /*
45 * obtain key from context, validate, convert to native FEE key
46 */
47 void CryptKit::FEESigner::keyFromContext(
48 const Context &context)
49 {
50 if(initFlag() && (mFeeKey != NULL)) {
51 /* reusing context, OK */
52 return;
53 }
54
55 CSSM_KEYCLASS keyClass;
56 CSSM_KEYUSE keyUse;
57 if(isSigning()) {
58 /* signing with private key */
59 keyClass = CSSM_KEYCLASS_PRIVATE_KEY;
60 keyUse = CSSM_KEYUSE_SIGN;
61 }
62 else {
63 /* verifying with public key */
64 keyClass = CSSM_KEYCLASS_PUBLIC_KEY;
65 keyUse = CSSM_KEYUSE_VERIFY;
66 }
67 if(mFeeKey == NULL) {
68 mFeeKey = contextToFeeKey(context,
69 mSession,
70 CSSM_ATTRIBUTE_KEY,
71 keyClass,
72 keyUse,
73 mWeMallocdFeeKey);
74 }
75 }
76
77 /* reusable init */
78 void CryptKit::FEESigner::signerInit(
79 const Context &context,
80 bool isSigning)
81 {
82 setIsSigning(isSigning);
83 keyFromContext(context);
84 setInitFlag(true);
85 }
86
87 /*
88 * Note that, unlike the implementation in security_cryptkit/feePublicKey.c, we ignore
89 * the Pm which used to be used as salt for the digest. That made staged verification
90 * impossible and I do not believe it increased security.
91 */
92 void CryptKit::FEERawSigner::sign(
93 const void *data,
94 size_t dataLen,
95 void *sig,
96 size_t *sigLen) /* IN/OUT */
97 {
98 feeSig fsig;
99 feeReturn frtn;
100 unsigned char *feeSig;
101 unsigned feeSigLen=0;
102
103 if(mFeeKey == NULL) {
104 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
105 }
106 fsig = feeSigNewWithKey(mFeeKey, mRandFcn, mRandRef);
107 if(fsig == NULL) {
108 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign");
109 }
110 frtn = feeSigSign(fsig,
111 (unsigned char *)data,
112 (unsigned)dataLen,
113 mFeeKey);
114 if(frtn == FR_Success) {
115 frtn = feeSigData(fsig, &feeSig, &feeSigLen);
116 }
117 feeSigFree(fsig);
118 if(frtn) {
119 throwCryptKit(frtn, "FEERawSigner::sign");
120 }
121
122 /* copy out to caller and ffree */
123 if(*sigLen < feeSigLen) {
124 feeSigObjDebug("FEERawSigner sign overflow\n");
125 ffree(feeSig);
126 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
127 }
128 memmove(sig, feeSig, feeSigLen);
129 *sigLen = feeSigLen;
130 ffree(feeSig);
131 }
132
133 void CryptKit::FEERawSigner::verify(
134 const void *data,
135 size_t dataLen,
136 const void *sig,
137 size_t sigLen)
138 {
139 feeSig fsig;
140 feeReturn frtn;
141
142 if(mFeeKey == NULL) {
143 throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)");
144 }
145 frtn = feeSigParse((unsigned char *)sig, sigLen, &fsig);
146 if(frtn) {
147 throwCryptKit(frtn, "feeSigParse");
148 }
149 frtn = feeSigVerify(fsig,
150 (unsigned char *)data,
151 (unsigned int)dataLen,
152 mFeeKey);
153 feeSigFree(fsig);
154 if(frtn) {
155 throwCryptKit(frtn, NULL);
156 }
157 }
158
159 size_t CryptKit::FEERawSigner::maxSigSize()
160 {
161 unsigned rtn;
162 feeReturn frtn;
163
164 frtn = feeSigSize(mFeeKey, &rtn);
165 if(frtn) {
166 throwCryptKit(frtn, "feeSigSize");
167 }
168 return rtn;
169 }
170
171 /* ECDSA - this is really easy. */
172
173 void CryptKit::FEEECDSASigner::sign(
174 const void *data,
175 size_t dataLen,
176 void *sig,
177 size_t *sigLen) /* IN/OUT */
178 {
179 unsigned char *feeSig;
180 unsigned feeSigLen;
181 feeReturn frtn;
182
183 if(mFeeKey == NULL) {
184 throwCryptKit(FR_BadPubKey, "FEERawSigner::sign (no key)");
185 }
186 frtn = feeECDSASign(mFeeKey,
187 (unsigned char *)data, // data to be signed
188 (unsigned int)dataLen, // in bytes
189 mRandFcn,
190 mRandRef,
191 &feeSig,
192 &feeSigLen);
193 if(frtn) {
194 throwCryptKit(frtn, "feeECDSASign");
195 }
196 /* copy out to caller and ffree */
197 if(*sigLen < feeSigLen) {
198 feeSigObjDebug("feeECDSASign overflow\n");
199 ffree(feeSig);
200 CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR);
201 }
202 memmove(sig, feeSig, feeSigLen);
203 *sigLen = feeSigLen;
204 ffree(feeSig);
205
206 }
207
208 void CryptKit::FEEECDSASigner::verify(
209 const void *data,
210 size_t dataLen,
211 const void *sig,
212 size_t sigLen)
213 {
214 feeReturn frtn;
215
216 if(mFeeKey == NULL) {
217 throwCryptKit(FR_BadPubKey, "FEERawSigner::verify (no key)");
218 }
219 frtn = feeECDSAVerify((unsigned char *)sig,
220 sigLen,
221 (unsigned char *)data,
222 (unsigned int)dataLen,
223 mFeeKey);
224 if(frtn) {
225 throwCryptKit(frtn, NULL);
226 }
227 }
228
229 size_t CryptKit::FEEECDSASigner::maxSigSize()
230 {
231 unsigned rtn;
232 feeReturn frtn;
233
234 frtn = feeECDSASigSize(mFeeKey, &rtn);
235 if(frtn) {
236 throwCryptKit(frtn, "feeECDSASigSize");
237 }
238 return rtn;
239 }
240
241 #endif /* CRYPTKIT_CSP_ENABLE */