1/*
2 * sha1.c --
3 *
4 *	Implements and registers message digest generator SHA1.
5 *
6 *
7 * Copyright (c) 1996 Andreas Kupries (a.kupries@westend.com)
8 * All rights reserved.
9 *
10 * Permission is hereby granted, without written agreement and without
11 * license or royalty fees, to use, copy, modify, and distribute this
12 * software and its documentation for any purpose, provided that the
13 * above copyright notice and the following two paragraphs appear in
14 * all copies of this software.
15 *
16 * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
17 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
18 * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE
19 * POSSIBILITY OF SUCH DAMAGE.
20 *
21 * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND
24 * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
25 * ENHANCEMENTS, OR MODIFICATIONS.
26 *
27 * CVS: $Id: sha1.c,v 1.3 2000/08/09 19:13:18 aku Exp $
28 */
29
30#include "loadman.h"
31
32/*
33 * Generator description
34 * ---------------------
35 *
36 * The SHA1 alogrithm is used to compute a cryptographically strong
37 * message digest.
38 */
39
40#ifndef OTP
41#define DIGEST_SIZE               (SHA_DIGEST_LENGTH)
42#else
43#define DIGEST_SIZE               (8)
44#endif
45#define CTX_TYPE                  SHA_CTX
46
47/*
48 * Declarations of internal procedures.
49 */
50
51static void MDsha1_Start     _ANSI_ARGS_ ((VOID* context));
52static void MDsha1_Update    _ANSI_ARGS_ ((VOID* context, unsigned int character));
53static void MDsha1_UpdateBuf _ANSI_ARGS_ ((VOID* context, unsigned char* buffer, int bufLen));
54static void MDsha1_Final     _ANSI_ARGS_ ((VOID* context, VOID* digest));
55static int  MDsha1_Check     _ANSI_ARGS_ ((Tcl_Interp* interp));
56
57/*
58 * Generator definition.
59 */
60
61static Trf_MessageDigestDescription mdDescription = { /* THREADING: constant, read-only => safe */
62#ifndef OTP
63  "sha1",
64#else
65  "otp_sha1",
66#endif
67  sizeof (CTX_TYPE),
68  DIGEST_SIZE,
69  MDsha1_Start,
70  MDsha1_Update,
71  MDsha1_UpdateBuf,
72  MDsha1_Final,
73  MDsha1_Check
74};
75
76/*
77 *------------------------------------------------------*
78 *
79 *	TrfInit_SHA1 --
80 *
81 *	------------------------------------------------*
82 *	Register the generator implemented in this file.
83 *	------------------------------------------------*
84 *
85 *	Sideeffects:
86 *		As of 'Trf_Register'.
87 *
88 *	Result:
89 *		A standard Tcl error code.
90 *
91 *------------------------------------------------------*
92 */
93
94int
95#ifndef OTP
96TrfInit_SHA1 (interp)
97#else
98TrfInit_OTP_SHA1 (interp)
99#endif
100Tcl_Interp* interp;
101{
102  return Trf_RegisterMessageDigest (interp, &mdDescription);
103}
104
105/*
106 *------------------------------------------------------*
107 *
108 *	MDsha1_Start --
109 *
110 *	------------------------------------------------*
111 *	Initialize the internal state of the message
112 *	digest generator.
113 *	------------------------------------------------*
114 *
115 *	Sideeffects:
116 *		As of the called procedure.
117 *
118 *	Result:
119 *		None.
120 *
121 *------------------------------------------------------*
122 */
123
124static void
125MDsha1_Start (context)
126VOID* context;
127{
128  sha1f.init ((SHA_CTX*) context);
129}
130
131/*
132 *------------------------------------------------------*
133 *
134 *	MDsha1_Update --
135 *
136 *	------------------------------------------------*
137 *	Update the internal state of the message digest
138 *	generator for a single character.
139 *	------------------------------------------------*
140 *
141 *	Sideeffects:
142 *		As of the called procedure.
143 *
144 *	Result:
145 *		None.
146 *
147 *------------------------------------------------------*
148 */
149
150static void
151MDsha1_Update (context, character)
152VOID* context;
153unsigned int   character;
154{
155  unsigned char buf = character;
156
157  sha1f.update ((SHA_CTX*) context, &buf, 1);
158}
159
160/*
161 *------------------------------------------------------*
162 *
163 *	MDsha1_UpdateBuf --
164 *
165 *	------------------------------------------------*
166 *	Update the internal state of the message digest
167 *	generator for a character buffer.
168 *	------------------------------------------------*
169 *
170 *	Sideeffects:
171 *		As of the called procedure.
172 *
173 *	Result:
174 *		None.
175 *
176 *------------------------------------------------------*
177 */
178
179static void
180MDsha1_UpdateBuf (context, buffer, bufLen)
181VOID* context;
182unsigned char* buffer;
183int   bufLen;
184{
185  sha1f.update ((SHA_CTX*) context, (unsigned char*) buffer, bufLen);
186}
187
188/*
189 *------------------------------------------------------*
190 *
191 *	MDsha1_Final --
192 *
193 *	------------------------------------------------*
194 *	Generate the digest from the internal state of
195 *	the message digest generator.
196 *	------------------------------------------------*
197 *
198 *	Sideeffects:
199 *		As of the called procedure.
200 *
201 *	Result:
202 *		None.
203 *
204 *------------------------------------------------------*
205 */
206
207static void
208MDsha1_Final (context, digest)
209VOID* context;
210VOID* digest;
211{
212#ifndef OTP
213  sha1f.final ((unsigned char*) digest, (SHA_CTX*) context);
214#else
215    unsigned int result[SHA_DIGEST_LENGTH / sizeof (char)];
216
217    sha1f.final ((unsigned char*) result, (SHA_CTX*) context);
218
219    result[0] ^= result[2];
220    result[1] ^= result[3];
221    result[0] ^= result[4];
222
223    Trf_FlipRegisterLong ((VOID*) result, DIGEST_SIZE);
224    memcpy ((VOID *) digest, (VOID *) result, DIGEST_SIZE);
225#endif
226}
227
228/*
229 *------------------------------------------------------*
230 *
231 *	MDsha1_Check --
232 *
233 *	------------------------------------------------*
234 *	Do global one-time initializations of the message
235 *	digest generator.
236 *	------------------------------------------------*
237 *
238 *	Sideeffects:
239 *		Loads the shared library containing the
240 *		SHA1 functionality
241 *
242 *	Result:
243 *		A standard Tcl error code.
244 *
245 *------------------------------------------------------*
246 */
247
248static int
249MDsha1_Check (interp)
250Tcl_Interp* interp;
251{
252  return TrfLoadSHA1 (interp);
253}
254