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