X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_cryptkit/lib/ckSHA1.c diff --git a/Security/libsecurity_cryptkit/lib/ckSHA1.c b/Security/libsecurity_cryptkit/lib/ckSHA1.c new file mode 100644 index 00000000..94a20a6a --- /dev/null +++ b/Security/libsecurity_cryptkit/lib/ckSHA1.c @@ -0,0 +1,227 @@ +/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. + * + * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT + * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE + * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE + * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, + * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL + * EXPOSE YOU TO LIABILITY. + *************************************************************************** + * + * ckSHA1.c - generic, portable SHA-1 hash object + * + * Revision History + * ---------------- + * 10/06/98 ap + * Changed to compile with C++. + * 07 Jan 1998 at Apple + * Created. + */ + +#include "ckconfig.h" +#include "feeTypes.h" +#include "ckSHA1.h" + +#if CRYPTKIT_LIBMD_DIGEST +/* + * For linking with AppleCSP: use libSystem SHA1 implementation. + */ +#include +#else +#include "ckSHA1_priv.h" +#endif +#include "falloc.h" +#include "platform.h" + +#if CRYPTKIT_LIBMD_DIGEST +/* + * Trivial wrapper for SHA_CTX; a sha1Obj is a pointer to this. + */ +typedef struct { + CC_SHA1_CTX ctx; + unsigned char digest[CC_SHA1_DIGEST_LENGTH]; +} Sha1Obj; + +sha1Obj sha1Alloc(void) +{ + void *rtn = fmalloc(sizeof(Sha1Obj)); + memset(rtn, 0, sizeof(Sha1Obj)); + CC_SHA1_Init(&(((Sha1Obj *)rtn)->ctx)); + return (sha1Obj)rtn; +} + +void sha1Reinit(sha1Obj sha1) +{ + Sha1Obj *ctx = (Sha1Obj *)sha1; + CC_SHA1_Init(&ctx->ctx); +} + +void sha1Free(sha1Obj sha1) +{ + memset(sha1, 0, sizeof(Sha1Obj)); + ffree(sha1); +} + +void sha1AddData(sha1Obj sha1, + const unsigned char *data, + unsigned dataLen) +{ + Sha1Obj *ctx = (Sha1Obj *)sha1; + CC_SHA1_Update(&ctx->ctx, data, dataLen); +} + +unsigned char *sha1Digest(sha1Obj sha1) +{ + Sha1Obj *ctx = (Sha1Obj *)sha1; + CC_SHA1_Final(ctx->digest, &ctx->ctx); + return ctx->digest; +} + +unsigned sha1DigestLen(void) +{ + return CC_SHA1_DIGEST_LENGTH; +} + +#else /* standalone cryptkit implementation */ + +/* + * Private data for this object. A sha1Obj handle is cast to a pointer + * to one of these. + */ +typedef struct { + SHS_INFO context; + int isDone; + + /* + * For storing partial blocks + */ + BYTE dataBuf[SHS_BLOCKSIZE]; + unsigned bufBytes; // valid bytes in dataBuf[p] +} sha1Inst; + +/* + * Alloc and init an empty sha1 object. + */ +sha1Obj sha1Alloc(void) +{ + sha1Inst *sinst; + + sinst = (sha1Inst *)fmalloc(sizeof(sha1Inst)); + if(sinst == NULL) { + return NULL; + } + shsInit(&sinst->context); + sha1Reinit((sha1Obj)sinst); + return (sha1Obj)sinst; +} + +/* + * Reusable init function. + */ +void sha1Reinit(sha1Obj sha1) +{ + sha1Inst *sinst = (sha1Inst *) sha1; + + shsInit(&sinst->context); + sinst->isDone = 0; + sinst->bufBytes = 0; +} + +/* + * Free an sha1 object. + */ +void sha1Free(sha1Obj sha1) +{ + sha1Inst *sinst = (sha1Inst *) sha1; + + memset(sha1, 0, sizeof(sha1Inst)); + ffree(sinst); +} + +/* + * Add some data to the sha1 object. + */ +void sha1AddData(sha1Obj sha1, + const unsigned char *data, + unsigned dataLen) +{ + sha1Inst *sinst = (sha1Inst *) sha1; + unsigned toMove; + unsigned blocks; + + if(sinst->isDone) { + /* + * Log some kind of error here... + */ + return; + } + + /* + * First deal with partial buffered block + */ + if(sinst->bufBytes != 0) { + toMove = SHS_BLOCKSIZE - sinst->bufBytes; + if(toMove > dataLen) { + toMove = dataLen; + } + memmove(sinst->dataBuf+sinst->bufBytes, data, toMove); + data += toMove; + dataLen -= toMove; + sinst->bufBytes += toMove; + if(sinst->bufBytes == SHS_BLOCKSIZE) { + shsUpdate(&sinst->context, sinst->dataBuf, SHS_BLOCKSIZE); + sinst->bufBytes = 0; + } + } + + /* + * Now the bulk of the data, in a multiple of full blocks + */ + blocks = dataLen / SHS_BLOCKSIZE; + toMove = blocks * SHS_BLOCKSIZE; + if(toMove != 0) { + shsUpdate(&sinst->context, data, toMove); + data += toMove; + dataLen -= toMove; + } + + /* + * Store any remainder in dataBuf + */ + if(dataLen != 0) { + memmove(sinst->dataBuf, data, dataLen); + sinst->bufBytes = dataLen; + } +} + +/* + * Obtain a pointer to completed message digest, and the length of the digest. + */ +unsigned char *sha1Digest(sha1Obj sha1) +{ + sha1Inst *sinst = (sha1Inst *) sha1; + + if(!sinst->isDone) { + /* + * Deal with partial resid block + */ + if(sinst->bufBytes != 0) { + shsUpdate(&sinst->context, sinst->dataBuf, + sinst->bufBytes); + sinst->bufBytes = 0; + } + shsFinal(&sinst->context); + sinst->isDone = 1; + } + /* + * FIXME - should do explicit conversion to char array....? + */ + return (unsigned char *)sinst->context.digest; +} + +unsigned sha1DigestLen(void) +{ + return SHS_DIGESTSIZE; +} + +#endif /* CRYPTKIT_LIBMD_DIGEST */