2 * Copyright (c) 2000-2001,2011,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.
18 #ifdef BSAFE_CSP_ENABLE
21 // miscalgorithms - miscellaneous BSafe context creators and managers
23 #include "bsafecspi.h"
25 #include <stdio.h> // debug
30 // NOTE: There is no init() method, since BSafe digest algorithms re-initialize
31 // automatically and there is no directional difference.
33 BSafe::DigestContext::DigestContext(
34 AppleCSPSession
&session
,
38 : BSafeContext(session
)
41 inUpdate
= B_DigestUpdate
;
42 outFinal
= B_DigestFinal
;
43 setAlgorithm(bAlgInfo
);
44 check(B_DigestInit(bsAlgorithm
, bsKey
, chooser(), bsSurrender
));
50 // Signing/Verifying algorithms
53 // We really should match the key algorithm to the sign/vfy
54 // algorithm. Also: verify key usage bits.
55 void BSafe::SigningContext::init(
56 const Context
&context
,
60 return; // all set to go
62 setAlgorithm(algorithm
, NULL
);
63 setKeyFromContext(context
); // may set outSize for some keys
66 check(B_SignInit(bsAlgorithm
, bsKey
, chooser(), bsSurrender
));
67 setRandom(); // needed by some signing algorithms
68 inUpdate
= B_SignUpdate
;
69 outFinalR
= B_SignFinal
;
72 check(B_VerifyInit(bsAlgorithm
, bsKey
, chooser(), bsSurrender
));
73 inUpdate
= B_VerifyUpdate
;
74 inFinalR
= B_VerifyFinal
;
82 // Note that BSafe treats MACs as digest algorithms - it has no MAC algorithm
83 // class. Thus, verifying consists of "digesting" followed by comparing the result.
85 // FIXME : what kind of key do we expect here? For now, any old
86 // symmetric key will work...
88 void BSafe::MacContext::init(
89 const Context
&context
,
93 return; // all set to go
95 B_DIGEST_SPECIFIER digestSpec
;
96 digestSpec
.digestInfoType
= algorithm
;
97 digestSpec
.digestInfoParams
= NULL
;
99 setAlgorithm(AI_HMAC
, &digestSpec
);
100 setKeyFromContext(context
);
101 check(B_DigestInit(bsAlgorithm
, bsKey
, chooser(), bsSurrender
));
104 inUpdate
= B_DigestUpdate
;
105 outFinal
= B_DigestFinal
;
107 inUpdate
= B_DigestUpdate
;
108 // need not set xxFinal - we override final().
112 void BSafe::MacContext::final(const CssmData
&in
)
114 // we need to perform a DigestFinal step into a temp buffer and compare to 'in'
115 void *digest
= normAllocator
->malloc(in
.length());
117 check(B_DigestFinal(bsAlgorithm
, POINTER(digest
), &length
, in
.length(), bsSurrender
));
118 bool verified
= length
== in
.length() && !memcmp(digest
, in
.data(), in
.length());
119 normAllocator
->free(digest
);
122 CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED
);
127 // Random-number generation algorithms.
128 // Note that we don't use bsRandom, since that's our internal fixed "best to use" method,
129 // not the one the user asked for.
130 // NOTE: We freeze the output size at init().
132 void BSafe::RandomContext::init(const Context
&context
, bool)
134 reset(); // throw away, we need to re-seed anyway
135 setAlgorithm(algorithm
, NULL
); // MD5 generator mode (RSA proprietary)
136 check(B_RandomInit(bsAlgorithm
, chooser(), bsSurrender
));
138 // set/freeze output size
139 mOutSize
= context
.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE
, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE
);
141 // seed the PRNG (if specified)
142 if (const CssmCryptoData
*seed
= context
.get
<CssmCryptoData
>(CSSM_ATTRIBUTE_SEED
)) {
143 const CssmData
&seedValue
= (*seed
)();
144 check(B_RandomUpdate(bsAlgorithm
, POINTER(seedValue
.data()), seedValue
.length(), bsSurrender
));
148 void BSafe::RandomContext::final(CssmData
&data
)
150 check(B_GenerateRandomBytes(bsAlgorithm
, POINTER(data
.data()), mOutSize
, bsSurrender
));
152 #endif /* BSAFE_CSP_ENABLE */