]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/ckSHA1.c
Security-57337.20.44.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / ckSHA1.c
1 /* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
2 *
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
10 *
11 * ckSHA1.c - generic, portable SHA-1 hash object
12 *
13 * Revision History
14 * ----------------
15 * 10/06/98 ap
16 * Changed to compile with C++.
17 * 07 Jan 1998 at Apple
18 * Created.
19 */
20
21 #include "ckconfig.h"
22 #include "feeTypes.h"
23 #include "ckSHA1.h"
24
25 #if CRYPTKIT_LIBMD_DIGEST
26 /*
27 * For linking with AppleCSP: use libSystem SHA1 implementation.
28 */
29 #include <CommonCrypto/CommonDigest.h>
30 #else
31 #include "ckSHA1_priv.h"
32 #endif
33 #include "falloc.h"
34 #include "platform.h"
35
36 #if CRYPTKIT_LIBMD_DIGEST
37 /*
38 * Trivial wrapper for SHA_CTX; a sha1Obj is a pointer to this.
39 */
40 typedef struct {
41 CC_SHA1_CTX ctx;
42 unsigned char digest[CC_SHA1_DIGEST_LENGTH];
43 } Sha1Obj;
44
45 sha1Obj sha1Alloc(void)
46 {
47 void *rtn = fmalloc(sizeof(Sha1Obj));
48 memset(rtn, 0, sizeof(Sha1Obj));
49 CC_SHA1_Init(&(((Sha1Obj *)rtn)->ctx));
50 return (sha1Obj)rtn;
51 }
52
53 void sha1Reinit(sha1Obj sha1)
54 {
55 Sha1Obj *ctx = (Sha1Obj *)sha1;
56 CC_SHA1_Init(&ctx->ctx);
57 }
58
59 void sha1Free(sha1Obj sha1)
60 {
61 memset(sha1, 0, sizeof(Sha1Obj));
62 ffree(sha1);
63 }
64
65 void sha1AddData(sha1Obj sha1,
66 const unsigned char *data,
67 unsigned dataLen)
68 {
69 Sha1Obj *ctx = (Sha1Obj *)sha1;
70 CC_SHA1_Update(&ctx->ctx, data, dataLen);
71 }
72
73 unsigned char *sha1Digest(sha1Obj sha1)
74 {
75 Sha1Obj *ctx = (Sha1Obj *)sha1;
76 CC_SHA1_Final(ctx->digest, &ctx->ctx);
77 return ctx->digest;
78 }
79
80 unsigned sha1DigestLen(void)
81 {
82 return CC_SHA1_DIGEST_LENGTH;
83 }
84
85 #else /* standalone cryptkit implementation */
86
87 /*
88 * Private data for this object. A sha1Obj handle is cast to a pointer
89 * to one of these.
90 */
91 typedef struct {
92 SHS_INFO context;
93 int isDone;
94
95 /*
96 * For storing partial blocks
97 */
98 BYTE dataBuf[SHS_BLOCKSIZE];
99 unsigned bufBytes; // valid bytes in dataBuf[p]
100 } sha1Inst;
101
102 /*
103 * Alloc and init an empty sha1 object.
104 */
105 sha1Obj sha1Alloc(void)
106 {
107 sha1Inst *sinst;
108
109 sinst = (sha1Inst *)fmalloc(sizeof(sha1Inst));
110 if(sinst == NULL) {
111 return NULL;
112 }
113 shsInit(&sinst->context);
114 sha1Reinit((sha1Obj)sinst);
115 return (sha1Obj)sinst;
116 }
117
118 /*
119 * Reusable init function.
120 */
121 void sha1Reinit(sha1Obj sha1)
122 {
123 sha1Inst *sinst = (sha1Inst *) sha1;
124
125 shsInit(&sinst->context);
126 sinst->isDone = 0;
127 sinst->bufBytes = 0;
128 }
129
130 /*
131 * Free an sha1 object.
132 */
133 void sha1Free(sha1Obj sha1)
134 {
135 sha1Inst *sinst = (sha1Inst *) sha1;
136
137 memset(sha1, 0, sizeof(sha1Inst));
138 ffree(sinst);
139 }
140
141 /*
142 * Add some data to the sha1 object.
143 */
144 void sha1AddData(sha1Obj sha1,
145 const unsigned char *data,
146 unsigned dataLen)
147 {
148 sha1Inst *sinst = (sha1Inst *) sha1;
149 unsigned toMove;
150 unsigned blocks;
151
152 if(sinst->isDone) {
153 /*
154 * Log some kind of error here...
155 */
156 return;
157 }
158
159 /*
160 * First deal with partial buffered block
161 */
162 if(sinst->bufBytes != 0) {
163 toMove = SHS_BLOCKSIZE - sinst->bufBytes;
164 if(toMove > dataLen) {
165 toMove = dataLen;
166 }
167 memmove(sinst->dataBuf+sinst->bufBytes, data, toMove);
168 data += toMove;
169 dataLen -= toMove;
170 sinst->bufBytes += toMove;
171 if(sinst->bufBytes == SHS_BLOCKSIZE) {
172 shsUpdate(&sinst->context, sinst->dataBuf, SHS_BLOCKSIZE);
173 sinst->bufBytes = 0;
174 }
175 }
176
177 /*
178 * Now the bulk of the data, in a multiple of full blocks
179 */
180 blocks = dataLen / SHS_BLOCKSIZE;
181 toMove = blocks * SHS_BLOCKSIZE;
182 if(toMove != 0) {
183 shsUpdate(&sinst->context, data, toMove);
184 data += toMove;
185 dataLen -= toMove;
186 }
187
188 /*
189 * Store any remainder in dataBuf
190 */
191 if(dataLen != 0) {
192 memmove(sinst->dataBuf, data, dataLen);
193 sinst->bufBytes = dataLen;
194 }
195 }
196
197 /*
198 * Obtain a pointer to completed message digest, and the length of the digest.
199 */
200 unsigned char *sha1Digest(sha1Obj sha1)
201 {
202 sha1Inst *sinst = (sha1Inst *) sha1;
203
204 if(!sinst->isDone) {
205 /*
206 * Deal with partial resid block
207 */
208 if(sinst->bufBytes != 0) {
209 shsUpdate(&sinst->context, sinst->dataBuf,
210 sinst->bufBytes);
211 sinst->bufBytes = 0;
212 }
213 shsFinal(&sinst->context);
214 sinst->isDone = 1;
215 }
216 /*
217 * FIXME - should do explicit conversion to char array....?
218 */
219 return (unsigned char *)sinst->context.digest;
220 }
221
222 unsigned sha1DigestLen(void)
223 {
224 return SHS_DIGESTSIZE;
225 }
226
227 #endif /* CRYPTKIT_LIBMD_DIGEST */