]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/lib/bsafecspi.h
Security-58286.270.3.0.1.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / lib / bsafecspi.h
1 /*
2 * Copyright (c) 2000-2001,2011,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 #ifdef BSAFE_CSP_ENABLE
19
20
21 //
22 // bsafecspi - implementation layer for C++ BSafe 4 interface
23 //
24 #ifndef _H_BSAFECSPI
25 #define _H_BSAFECSPI
26
27 #include <security_cdsa_plugin/CSPsession.h>
28 #include "bsobjects.h"
29 #include "AppleCSPContext.h"
30 #include "AppleCSPSession.h"
31 #include <aglobal.h>
32 #include <bsafe.h>
33
34 //
35 // The BSafe class is more of a namespace than anything else.
36 // Just think of it as the "static binder" for BSafe's objects.
37 // Note that we keep a global, static allocator. We have to; BSafe
38 // doesn't have any state management at that level.
39 //
40 class BSafe {
41 class BSafeContext; friend class BSafeContext;
42 class BSafeFactory; friend class BSafeFactory;
43
44 public:
45 static void setNormAllocator(Allocator *alloc)
46 { assert(!normAllocator); normAllocator = alloc; }
47 static void setPrivAllocator(Allocator *alloc)
48 { assert(!privAllocator); privAllocator = alloc; }
49
50 static bool setup(
51 AppleCSPSession &session,
52 CSPFullPluginSession::CSPContext * &cspCtx,
53 const Context &context);
54
55 private:
56 // BSafe's memory allocators
57 static Allocator *normAllocator;
58 static Allocator *privAllocator;
59 friend POINTER T_malloc(unsigned int);
60 friend void T_free(POINTER);
61 friend POINTER T_realloc(POINTER, unsigned int);
62
63 static const B_ALGORITHM_METHOD * const bsChooser[];
64
65 private:
66 // BSafe-specific BinaryKey class.
67 class BSafeBinaryKey : public BinaryKey {
68
69 public:
70 BSafeBinaryKey(
71 bool isPub,
72 uint32 alg); // CSSM_ALGID_{RSA,DSA}
73 ~BSafeBinaryKey();
74 void generateKeyBlob(
75 Allocator &allocator,
76 CssmData &blob,
77 CSSM_KEYBLOB_FORMAT &format,
78 AppleCSPSession &session,
79 const CssmKey *paramKey, /* optional, unused here */
80 CSSM_KEYATTR_FLAGS &attrFlags); /* IN/OUT */
81
82 bool isPublic() { return mIsPublic; }
83 uint32 alg() { return mAlg; }
84 B_KEY_OBJ bsKey() { return mBsKey; }
85
86 private:
87 bool mIsPublic;
88 uint32 mAlg; // CSSM_ALGID_{RSA,DSA}
89 B_KEY_OBJ mBsKey;
90 };
91
92 private:
93 //
94 // The BSafeContext class is the parent of all BSafe-used CSPContext objects.
95 // It implements the CSPContext operation functions (init, update, ...) in terms
96 // of pointer-to-member fields set by its subclasses. This may not be pretty, but
97 // it avoids every subclass having to re-implement all CSPContext operations.
98 // Beyond that, we implement a raftload of utility methods for our children.
99 //
100 class BSafeContext : public AppleCSPContext {
101 friend class BSafe;
102 public:
103 BSafeContext(AppleCSPSession &session);
104 virtual ~BSafeContext();
105
106 // called by CSPFullPluginSession
107 void init(const Context &context, bool encoding = true);
108 void update(const CssmData &data);
109 void update(void *inp, size_t &inSize, void *outp, size_t &outSize);
110 void final(CssmData &out);
111 void final(const CssmData &in);
112 size_t outputSize(bool final, size_t inSize);
113
114 protected:
115 // install a BSafe algorithm into bsAlgorithm
116 void setAlgorithm(B_INFO_TYPE bAlgType, const void *info = NULL);
117
118 // safely create bsKey
119 void createBsKey();
120
121 // set bsKey. The different versions are equivalent
122 void setKeyAtom(B_INFO_TYPE bKeyInfo, const void *info);
123 void setKeyFromItem(B_INFO_TYPE bKeyInfo, const BSafeItem &item)
124 { setKeyAtom(bKeyInfo, &item); }
125 void setKeyFromCssmKey(B_INFO_TYPE bKeyInfo, const CssmKey &key)
126 { BSafeItem item(key.KeyData); setKeyAtom(bKeyInfo, &item); }
127 void setKeyFromCssmData(B_INFO_TYPE bKeyInfo, const CssmData &keyData)
128 { BSafeItem item(keyData); setKeyAtom(bKeyInfo, &item); }
129 void setKeyFromContext(const Context &context, bool required = true);
130
131 void setRefKey(CssmKey &key);
132 void setRsaOutSize(bool isPubKey);
133
134 // create mRandom to be a suitable random-generator BSafe object (if it isn't yet)
135 void setRandom();
136
137 // trackUpdate is called during crypto-output. Hook it to keep track of data flow
138 virtual void trackUpdate(size_t in, size_t out);
139
140 // destroy bsAlgorithm and bsKey so we can start over making them
141 void reset();
142
143 // clear key state
144 void destroyBsKey();
145
146 // determine if we can reuse the current bsAlgorithm
147 bool reusing(bool encode = true)
148 {
149 if (initialized && !opStarted &&
150 (encode == encoding)) return true;
151 encoding = encode;
152 return false;
153 }
154
155 public:
156 //
157 // These pointers-to-member are called by the BSafeContext operations
158 // (update, final). They must be set by a subclasses's init() method.
159 // Not all members are used by all types of operations - check the
160 // source when in doubt.
161 //
162 int (*inUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *);
163 int (*inOutUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
164 POINTER, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
165 int (*inFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *);
166 int (*inFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int,
167 B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
168 int (*outFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
169 B_ALGORITHM_OBJ, A_SURRENDER_CTX *);
170 int (*outFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int,
171 A_SURRENDER_CTX *);
172
173 protected:
174
175 // un-consted bsChooser for BSafe's consumption. BSafe's Bad
176 static B_ALGORITHM_METHOD **chooser()
177 { return const_cast<B_ALGORITHM_METHOD **>(bsChooser); }
178
179 // a placeholder for a surrender context. Not currently used
180 // @@@ should perhaps test for pthread cancel? --> thread abstraction
181 static A_SURRENDER_CTX * const bsSurrender;
182
183 protected:
184 B_ALGORITHM_OBJ bsAlgorithm; // BSafe algorithm object or NULL
185 B_ALGORITHM_OBJ bsRandom; // PRNG algorithm
186 bool encoding; // encoding direction
187 bool initialized; // method init() has completed
188 bool opStarted; // method update() has been called
189 // generally means that we can't reuse
190 // the current bsAlgorithm
191 //
192 // We have a binKey only if the caller passed in a reference
193 // key. In that case we avoid deleting bsKey - which is a copy
194 // of binKey.bsKey - because a BinaryKey is persistent
195 // relative to this context.
196 //
197 BSafeBinaryKey *bsBinKey;
198 B_KEY_OBJ bsKey; // BSafe key object or NULL
199
200 size_t mOutSize; // simple output size, if applicable
201 }; /* BSafeContext */
202
203 // contexts for BSafe digest operations
204 class DigestContext : public BSafeContext {
205 public:
206 // do all work in constructor. We have no directions; thus default init() works fine
207 DigestContext(
208 AppleCSPSession &session,
209 const Context &,
210 B_INFO_TYPE bAlgInfo,
211 size_t sz);
212 };
213
214 // common context features for BSafe cipher operations (both symmetric and asymmetric)
215 class CipherContext : public BSafeContext {
216 public:
217 CipherContext(
218 AppleCSPSession &session) :
219 BSafeContext(session),
220 pending(0) {}
221
222 protected:
223 size_t pending; // bytes not eaten still pending (staged only)
224 public:
225 void cipherInit(); // common init code (must be called from init())
226 };
227
228 // contexts for block cipher operations using symmetric algorithms
229 class BlockCipherContext : public CipherContext {
230 size_t blockSize;
231 uint32 cssmAlg;
232 uint32 cssmMode;
233 bool padEnable;
234 public:
235 BlockCipherContext(
236 AppleCSPSession &session,
237 const Context &,
238 size_t sz) :
239 CipherContext(session),
240 blockSize(sz) { }
241 void init(const Context &context, bool encrypting);
242 size_t inputSize(size_t outSize);
243 size_t outputSize(bool final, size_t inSize);
244 void minimumProgress(size_t &in, size_t &out);
245 void trackUpdate(size_t in, size_t out);
246 private:
247 // special case for RC4
248 void RC4init(const Context &context);
249 };
250
251 // context for generating public/private key pairs
252 class BSafeKeyPairGenContext : public BSafeContext,
253 private AppleKeyPairGenContext {
254 public:
255 BSafeKeyPairGenContext(
256 AppleCSPSession &session,
257 const Context &) :
258 BSafeContext(session) {}
259
260 // generate alg params, not handled by PublicKeyGenerateContext
261 // For DSA only.
262 void generate(
263 const Context &context,
264 uint32 bitSize,
265 CssmData &params,
266 uint32 &attrCount,
267 Context::Attr * &attrs);
268
269 // this one is specified in CSPFullPluginSession
270 void generate(
271 const Context &context,
272 CssmKey &pubKey,
273 CssmKey &privKey);
274
275 // this one in AppleKeyPairGenContext
276 void generate(
277 const Context &context,
278 BinaryKey &pubBinKey,
279 BinaryKey &privBinKey,
280 uint32 &keySize);
281
282 private:
283 void setupAlgorithm(
284 const Context &context,
285 uint32 &keySize);
286
287 }; /* BSafeKeyPairGenContext */
288
289 // public key cipher operations
290 class PublicKeyCipherContext : public CipherContext {
291 public:
292 PublicKeyCipherContext(
293 AppleCSPSession &session,
294 const Context &) :
295 CipherContext(session) { }
296 void init(const Context &context, bool encrypting);
297 size_t inputSize(size_t outSize); // unlimited
298 };
299
300 // contexts for BSafe signing/verifying operations
301 class SigningContext : public BSafeContext {
302 B_INFO_TYPE algorithm;
303 public:
304 SigningContext(
305 AppleCSPSession &session,
306 const Context &,
307 B_INFO_TYPE bAlg,
308 size_t sz) :
309 BSafeContext(session),
310 algorithm(bAlg) { mOutSize = sz; }
311 void init(const Context &context, bool signing);
312 };
313
314 // contexts for BSafe MAC generation and verification
315 class MacContext : public BSafeContext {
316 B_INFO_TYPE algorithm;
317 public:
318 MacContext(
319 AppleCSPSession &session,
320 const Context &,
321 B_INFO_TYPE bAlg,
322 size_t sz) :
323 BSafeContext(session),
324 algorithm(bAlg) { mOutSize = sz; }
325 void init(const Context &context, bool signing);
326 void final(const CssmData &in);
327 };
328
329 // contexts for BSafe's random number generation
330 class RandomContext : public BSafeContext {
331 B_INFO_TYPE algorithm;
332 public:
333 RandomContext(
334 AppleCSPSession &session,
335 const Context &,
336 B_INFO_TYPE alg) :
337 BSafeContext(session),
338 algorithm(alg) { }
339 void init(const Context &context, bool);
340 void final(CssmData &data);
341 };
342
343 // symmetric key generation context
344 class SymmetricKeyGenContext : public BSafeContext,
345 private AppleSymmKeyGenContext {
346 public:
347 SymmetricKeyGenContext(
348 AppleCSPSession &session,
349 const Context &ctx,
350 uint32 minSizeInBits,
351 uint32 maxSizeInBits,
352 bool mustBeByteSized) :
353 BSafeContext(session),
354 AppleSymmKeyGenContext(
355 minSizeInBits,
356 maxSizeInBits,
357 mustBeByteSized) { }
358
359 void generate(
360 const Context &context,
361 CssmKey &symKey,
362 CssmKey &dummyKey);
363
364 };
365
366 public:
367 /*
368 * Stateless, private function to map a CSSM alg and pub/priv state
369 * to B_INFO_TYPE and format. Returns true on success, false on
370 * "I don't understand this algorithm".
371 */
372 static bool bsafeAlgToInfoType(
373 CSSM_ALGORITHMS alg,
374 bool isPublic,
375 B_INFO_TYPE &infoType, // RETURNED
376 CSSM_KEYBLOB_FORMAT &format); // RETURNED
377
378 /* check result of a BSafe call and throw on error */
379 static void check(int status, bool isKeyOp = false);
380
381 /* moved here from BSafeContext - now works on any key */
382 template <class KI_Type>
383 static KI_Type *getKey(B_KEY_OBJ bKey, B_INFO_TYPE type)
384 {
385 POINTER p;
386 check(B_GetKeyInfo(&p, bKey, type), true);
387 return reinterpret_cast<KI_Type *>(p);
388 }
389
390
391 //
392 // The context generation table - see algmaker.cpp.
393 //
394 public:
395 // Base class for Maker classes
396 class MakerBase {
397 public:
398 virtual ~MakerBase() { }
399 virtual BSafeContext *make(
400 AppleCSPSession &session,
401 const Context &context) const = 0;
402 };
403
404 // One entry in Maker table
405 struct MakerTable {
406 CSSM_ALGORITHMS algorithmId;
407 CSSM_CONTEXT_TYPE algClass;
408 const MakerBase *maker;
409 ~MakerTable() { delete maker; }
410 };
411
412 private:
413 static bug_const MakerTable algorithms[];
414 static const unsigned int algorithmCount;
415
416 /*
417 * CSPKeyInfoProvider for BSafe keys
418 */
419 class BSafeKeyInfoProvider : public CSPKeyInfoProvider
420 {
421 private:
422 BSafeKeyInfoProvider(
423 const CssmKey &cssmKey,
424 AppleCSPSession &session);
425 public:
426 static CSPKeyInfoProvider *provider(
427 const CssmKey &cssmKey,
428 AppleCSPSession &session);
429 ~BSafeKeyInfoProvider() { }
430 void CssmKeyToBinary(
431 CssmKey *paramKey, // optional
432 CSSM_KEYATTR_FLAGS &attrFlags, // IN/OUT
433 BinaryKey **binKey); // RETURNED
434 void QueryKeySizeInBits(
435 CSSM_KEY_SIZE &keySize); // RETURNED
436 };
437
438 }; /* BSAFE namespace */
439
440 /*
441 * BSAFE Key Info types.
442 */
443 #define BLOB_IS_PUB_KEY_INFO 0
444
445 #if BLOB_IS_PUB_KEY_INFO
446
447 /* X beta values */
448 #define RSA_PUB_KEYINFO_TYPE KI_RSAPublicBER
449 #define RSA_PRIV_KEYINFO_TYPE KI_PKCS_RSAPrivateBER
450 #define DSA_PUB_KEYINFO_TYPE KI_DSAPublicBER
451 #define DSA_PRIV_KEYINFO_TYPE KI_DSAPrivateBER
452
453 #else /* BLOB_IS_PUB_KEY_INFO */
454
455 #define RSA_PUB_KEYINFO_TYPE KI_RSAPublic
456 #define RSA_PRIV_KEYINFO_TYPE KI_PKCS_RSAPrivateBER
457 #define DSA_PUB_KEYINFO_TYPE KI_DSAPublicBER
458 #define DSA_PRIV_KEYINFO_TYPE KI_DSAPrivateBER
459
460 #endif
461
462 #endif //_H_BSAFECSP
463 #endif /* BSAFE_CSP_ENABLE */