]>
Commit | Line | Data |
---|---|---|
d8f41ccd | 1 | /* Copyright (c) 1998,2004 Apple Computer, Inc. All Rights Reserved. |
b1ab9ed8 A |
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 COMPUTER, INC. AND THE | |
6 | * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER, | |
7 | * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL | |
8 | * EXPOSE YOU TO LIABILITY. | |
9 | *************************************************************************** | |
10 | * | |
d8f41ccd | 11 | * SHA1.c - generic, portable SHA-1 hash object |
b1ab9ed8 A |
12 | * |
13 | * Revision History | |
14 | * ---------------- | |
15 | * 10/06/98 ap | |
16 | * Changed to compile with C++. | |
17 | * 07 Jan 1998 Doug Mitchell at Apple | |
18 | * Created. | |
19 | */ | |
b1ab9ed8 | 20 | |
d8f41ccd A |
21 | #include "SHA1.h" |
22 | #include "SHA1_priv.h" | |
23 | #include <strings.h> | |
b1ab9ed8 | 24 | |
d8f41ccd A |
25 | /* for now map falloc to malloc, FIXME */ |
26 | #include <stdlib.h> | |
27 | #define fmalloc(s) malloc(s) | |
28 | #define ffree(p) free(p) | |
b1ab9ed8 A |
29 | |
30 | /* | |
31 | * Private data for this object. A sha1Obj handle is cast to a pointer | |
32 | * to one of these. | |
33 | */ | |
34 | typedef struct { | |
35 | SHS_INFO context; | |
36 | int isDone; | |
37 | ||
38 | /* | |
39 | * For storing partial blocks | |
40 | */ | |
41 | BYTE dataBuf[SHS_BLOCKSIZE]; | |
42 | unsigned bufBytes; // valid bytes in dataBuf[p] | |
43 | } sha1Inst; | |
44 | ||
45 | /* | |
46 | * Alloc and init an empty sha1 object. | |
47 | */ | |
48 | sha1Obj sha1Alloc(void) | |
49 | { | |
50 | sha1Inst *sinst; | |
51 | ||
52 | sinst = (sha1Inst *)fmalloc(sizeof(sha1Inst)); | |
53 | if(sinst == NULL) { | |
54 | return NULL; | |
55 | } | |
56 | shsInit(&sinst->context); | |
57 | sha1Reinit((sha1Obj)sinst); | |
58 | return (sha1Obj)sinst; | |
59 | } | |
60 | ||
61 | /* | |
62 | * Reusable init function. | |
63 | */ | |
64 | void sha1Reinit(sha1Obj sha1) | |
65 | { | |
66 | sha1Inst *sinst = (sha1Inst *) sha1; | |
67 | ||
68 | shsInit(&sinst->context); | |
69 | sinst->isDone = 0; | |
70 | sinst->bufBytes = 0; | |
71 | } | |
72 | ||
73 | /* | |
74 | * Free an sha1 object. | |
75 | */ | |
76 | void sha1Free(sha1Obj sha1) | |
77 | { | |
78 | sha1Inst *sinst = (sha1Inst *) sha1; | |
79 | ||
80 | memset(sha1, 0, sizeof(sha1Inst)); | |
81 | ffree(sinst); | |
82 | } | |
83 | ||
84 | /* | |
85 | * Add some data to the sha1 object. | |
86 | */ | |
87 | void sha1AddData(sha1Obj sha1, | |
88 | const unsigned char *data, | |
89 | unsigned dataLen) | |
90 | { | |
91 | sha1Inst *sinst = (sha1Inst *) sha1; | |
92 | unsigned toMove; | |
93 | unsigned blocks; | |
94 | ||
95 | if(sinst->isDone) { | |
96 | /* | |
97 | * Log some kind of error here... | |
98 | */ | |
99 | return; | |
100 | } | |
101 | ||
102 | /* | |
103 | * First deal with partial buffered block | |
104 | */ | |
105 | if(sinst->bufBytes != 0) { | |
106 | toMove = SHS_BLOCKSIZE - sinst->bufBytes; | |
107 | if(toMove > dataLen) { | |
108 | toMove = dataLen; | |
109 | } | |
110 | memmove(sinst->dataBuf+sinst->bufBytes, data, toMove); | |
111 | data += toMove; | |
112 | dataLen -= toMove; | |
113 | sinst->bufBytes += toMove; | |
114 | if(sinst->bufBytes == SHS_BLOCKSIZE) { | |
115 | shsUpdate(&sinst->context, sinst->dataBuf, SHS_BLOCKSIZE); | |
116 | sinst->bufBytes = 0; | |
117 | } | |
118 | } | |
119 | ||
120 | /* | |
121 | * Now the bulk of the data, in a multiple of full blocks | |
122 | */ | |
123 | blocks = dataLen / SHS_BLOCKSIZE; | |
124 | toMove = blocks * SHS_BLOCKSIZE; | |
125 | if(toMove != 0) { | |
126 | shsUpdate(&sinst->context, data, toMove); | |
127 | data += toMove; | |
128 | dataLen -= toMove; | |
129 | } | |
130 | ||
131 | /* | |
132 | * Store any remainder in dataBuf | |
133 | */ | |
134 | if(dataLen != 0) { | |
135 | memmove(sinst->dataBuf, data, dataLen); | |
136 | sinst->bufBytes = dataLen; | |
137 | } | |
138 | } | |
139 | ||
140 | /* | |
141 | * Obtain a pointer to completed message digest, and the length of the digest. | |
142 | */ | |
143 | unsigned char *sha1Digest(sha1Obj sha1) | |
144 | { | |
145 | sha1Inst *sinst = (sha1Inst *) sha1; | |
146 | ||
147 | if(!sinst->isDone) { | |
148 | /* | |
149 | * Deal with partial resid block | |
150 | */ | |
151 | if(sinst->bufBytes != 0) { | |
152 | shsUpdate(&sinst->context, sinst->dataBuf, | |
153 | sinst->bufBytes); | |
154 | sinst->bufBytes = 0; | |
155 | } | |
156 | shsFinal(&sinst->context); | |
157 | sinst->isDone = 1; | |
158 | } | |
159 | /* | |
160 | * FIXME - should do explicit conversion to char array....? | |
161 | */ | |
162 | return (unsigned char *)sinst->context.digest; | |
163 | } | |
164 | ||
d8f41ccd A |
165 | /* As above, with copy. */ |
166 | void sha1GetDigest(sha1Obj sha1, | |
167 | unsigned char *digest) | |
168 | { | |
169 | unsigned char *dig = sha1Digest(sha1); | |
170 | memmove(digest, dig, SHS_DIGESTSIZE); | |
171 | } | |
172 | ||
b1ab9ed8 A |
173 | unsigned sha1DigestLen(void) |
174 | { | |
175 | return SHS_DIGESTSIZE; | |
176 | } |