X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_apple_csp/lib/miscalgorithms.cpp diff --git a/libsecurity_apple_csp/lib/miscalgorithms.cpp b/libsecurity_apple_csp/lib/miscalgorithms.cpp new file mode 100644 index 00000000..4934cf22 --- /dev/null +++ b/libsecurity_apple_csp/lib/miscalgorithms.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + +#ifdef BSAFE_CSP_ENABLE + +// +// miscalgorithms - miscellaneous BSafe context creators and managers +// +#include "bsafecspi.h" + +#include // debug + + +// +// Digest algorithms. +// NOTE: There is no init() method, since BSafe digest algorithms re-initialize +// automatically and there is no directional difference. +// +BSafe::DigestContext::DigestContext( + AppleCSPSession &session, + const Context &, + B_INFO_TYPE bAlgInfo, + size_t sz) + : BSafeContext(session) +{ + mOutSize = sz; + inUpdate = B_DigestUpdate; + outFinal = B_DigestFinal; + setAlgorithm(bAlgInfo); + check(B_DigestInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); + initialized = true; +} + + +// +// Signing/Verifying algorithms +// +// FIXME: +// We really should match the key algorithm to the sign/vfy +// algorithm. Also: verify key usage bits. +void BSafe::SigningContext::init( + const Context &context, + bool signing) +{ + if (reusing(signing)) + return; // all set to go + + setAlgorithm(algorithm, NULL); + setKeyFromContext(context); // may set outSize for some keys + + if (signing) { + check(B_SignInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); + setRandom(); // needed by some signing algorithms + inUpdate = B_SignUpdate; + outFinalR = B_SignFinal; + outFinal = NULL; + } else { + check(B_VerifyInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); + inUpdate = B_VerifyUpdate; + inFinalR = B_VerifyFinal; + inFinal = NULL; + } +} + + +// +// MAC algorithms. +// Note that BSafe treats MACs as digest algorithms - it has no MAC algorithm +// class. Thus, verifying consists of "digesting" followed by comparing the result. +// +// FIXME : what kind of key do we expect here? For now, any old +// symmetric key will work... +// +void BSafe::MacContext::init( + const Context &context, + bool signing) +{ + if (reusing(signing)) + return; // all set to go + + B_DIGEST_SPECIFIER digestSpec; + digestSpec.digestInfoType = algorithm; + digestSpec.digestInfoParams = NULL; + + setAlgorithm(AI_HMAC, &digestSpec); + setKeyFromContext(context); + check(B_DigestInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); + + if (signing) { + inUpdate = B_DigestUpdate; + outFinal = B_DigestFinal; + } else { + inUpdate = B_DigestUpdate; + // need not set xxFinal - we override final(). + } +} + +void BSafe::MacContext::final(const CssmData &in) +{ + // we need to perform a DigestFinal step into a temp buffer and compare to 'in' + void *digest = normAllocator->malloc(in.length()); + unsigned int length; + check(B_DigestFinal(bsAlgorithm, POINTER(digest), &length, in.length(), bsSurrender)); + bool verified = length == in.length() && !memcmp(digest, in.data(), in.length()); + normAllocator->free(digest); + initialized = false; + if (!verified) + CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); +} + + +// +// Random-number generation algorithms. +// Note that we don't use bsRandom, since that's our internal fixed "best to use" method, +// not the one the user asked for. +// NOTE: We freeze the output size at init(). +// +void BSafe::RandomContext::init(const Context &context, bool) +{ + reset(); // throw away, we need to re-seed anyway + setAlgorithm(algorithm, NULL); // MD5 generator mode (RSA proprietary) + check(B_RandomInit(bsAlgorithm, chooser(), bsSurrender)); + + // set/freeze output size + mOutSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE); + + // seed the PRNG (if specified) + if (const CssmCryptoData *seed = context.get(CSSM_ATTRIBUTE_SEED)) { + const CssmData &seedValue = (*seed)(); + check(B_RandomUpdate(bsAlgorithm, POINTER(seedValue.data()), seedValue.length(), bsSurrender)); + } +} + +void BSafe::RandomContext::final(CssmData &data) +{ + check(B_GenerateRandomBytes(bsAlgorithm, POINTER(data.data()), mOutSize, bsSurrender)); +} +#endif /* BSAFE_CSP_ENABLE */