OpenSSL
1.0.1c
Main Page
Classes
Files
File List
File Members
All
Classes
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
crypto
evp
digest.c
Go to the documentation of this file.
1
/* crypto/evp/digest.c */
2
/* Copyright (C) 1995-1998 Eric Young (
[email protected]
)
3
* All rights reserved.
4
*
5
* This package is an SSL implementation written
6
* by Eric Young (
[email protected]
).
7
* The implementation was written so as to conform with Netscapes SSL.
8
*
9
* This library is free for commercial and non-commercial use as long as
10
* the following conditions are aheared to. The following conditions
11
* apply to all code found in this distribution, be it the RC4, RSA,
12
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
13
* included with this distribution is covered by the same copyright terms
14
* except that the holder is Tim Hudson (
[email protected]
).
15
*
16
* Copyright remains Eric Young's, and as such any Copyright notices in
17
* the code are not to be removed.
18
* If this package is used in a product, Eric Young should be given attribution
19
* as the author of the parts of the library used.
20
* This can be in the form of a textual message at program startup or
21
* in documentation (online or textual) provided with the package.
22
*
23
* Redistribution and use in source and binary forms, with or without
24
* modification, are permitted provided that the following conditions
25
* are met:
26
* 1. Redistributions of source code must retain the copyright
27
* notice, this list of conditions and the following disclaimer.
28
* 2. Redistributions in binary form must reproduce the above copyright
29
* notice, this list of conditions and the following disclaimer in the
30
* documentation and/or other materials provided with the distribution.
31
* 3. All advertising materials mentioning features or use of this software
32
* must display the following acknowledgement:
33
* "This product includes cryptographic software written by
34
* Eric Young (
[email protected]
)"
35
* The word 'cryptographic' can be left out if the rouines from the library
36
* being used are not cryptographic related :-).
37
* 4. If you include any Windows specific code (or a derivative thereof) from
38
* the apps directory (application code) you must include an acknowledgement:
39
* "This product includes software written by Tim Hudson (
[email protected]
)"
40
*
41
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
* SUCH DAMAGE.
52
*
53
* The licence and distribution terms for any publically available version or
54
* derivative of this code cannot be changed. i.e. this code cannot simply be
55
* copied and put under another distribution licence
56
* [including the GNU Public Licence.]
57
*/
58
/* ====================================================================
59
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60
*
61
* Redistribution and use in source and binary forms, with or without
62
* modification, are permitted provided that the following conditions
63
* are met:
64
*
65
* 1. Redistributions of source code must retain the above copyright
66
* notice, this list of conditions and the following disclaimer.
67
*
68
* 2. Redistributions in binary form must reproduce the above copyright
69
* notice, this list of conditions and the following disclaimer in
70
* the documentation and/or other materials provided with the
71
* distribution.
72
*
73
* 3. All advertising materials mentioning features or use of this
74
* software must display the following acknowledgment:
75
* "This product includes software developed by the OpenSSL Project
76
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77
*
78
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79
* endorse or promote products derived from this software without
80
* prior written permission. For written permission, please contact
81
*
[email protected]
.
82
*
83
* 5. Products derived from this software may not be called "OpenSSL"
84
* nor may "OpenSSL" appear in their names without prior written
85
* permission of the OpenSSL Project.
86
*
87
* 6. Redistributions of any form whatsoever must retain the following
88
* acknowledgment:
89
* "This product includes software developed by the OpenSSL Project
90
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91
*
92
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103
* OF THE POSSIBILITY OF SUCH DAMAGE.
104
* ====================================================================
105
*
106
* This product includes cryptographic software written by Eric Young
107
* (
[email protected]
). This product includes software written by Tim
108
* Hudson (
[email protected]
).
109
*
110
*/
111
112
#include <stdio.h>
113
#include "
cryptlib.h
"
114
#include <
openssl/objects.h
>
115
#include <
openssl/evp.h
>
116
#ifndef OPENSSL_NO_ENGINE
117
#include <
openssl/engine.h
>
118
#endif
119
120
#ifdef OPENSSL_FIPS
121
#include <openssl/fips.h>
122
#endif
123
124
void
EVP_MD_CTX_init
(
EVP_MD_CTX
*ctx)
125
{
126
memset(ctx,
'\0'
,
sizeof
*ctx);
127
}
128
129
EVP_MD_CTX
*
EVP_MD_CTX_create
(
void
)
130
{
131
EVP_MD_CTX
*ctx=
OPENSSL_malloc
(
sizeof
*ctx);
132
133
if
(ctx)
134
EVP_MD_CTX_init
(ctx);
135
136
return
ctx;
137
}
138
139
int
EVP_DigestInit
(
EVP_MD_CTX
*ctx,
const
EVP_MD
*
type
)
140
{
141
EVP_MD_CTX_init
(ctx);
142
return
EVP_DigestInit_ex
(ctx, type, NULL);
143
}
144
145
int
EVP_DigestInit_ex
(
EVP_MD_CTX
*ctx,
const
EVP_MD
*
type
,
ENGINE
*impl)
146
{
147
EVP_MD_CTX_clear_flags
(ctx,
EVP_MD_CTX_FLAG_CLEANED
);
148
#ifndef OPENSSL_NO_ENGINE
149
/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
150
* so this context may already have an ENGINE! Try to avoid releasing
151
* the previous handle, re-querying for an ENGINE, and having a
152
* reinitialisation, when it may all be unecessary. */
153
if
(ctx->
engine
&& ctx->
digest
&& (!type ||
154
(type && (type->
type
== ctx->
digest
->
type
))))
155
goto
skip_to_init;
156
if
(type)
157
{
158
/* Ensure an ENGINE left lying around from last time is cleared
159
* (the previous check attempted to avoid this if the same
160
* ENGINE and EVP_MD could be used). */
161
if
(ctx->
engine
)
162
ENGINE_finish
(ctx->
engine
);
163
if
(impl)
164
{
165
if
(!
ENGINE_init
(impl))
166
{
167
EVPerr
(
EVP_F_EVP_DIGESTINIT_EX
,
EVP_R_INITIALIZATION_ERROR
);
168
return
0;
169
}
170
}
171
else
172
/* Ask if an ENGINE is reserved for this job */
173
impl =
ENGINE_get_digest_engine
(type->
type
);
174
if
(impl)
175
{
176
/* There's an ENGINE for this job ... (apparently) */
177
const
EVP_MD
*d =
ENGINE_get_digest
(impl, type->
type
);
178
if
(!d)
179
{
180
/* Same comment from evp_enc.c */
181
EVPerr
(
EVP_F_EVP_DIGESTINIT_EX
,
EVP_R_INITIALIZATION_ERROR
);
182
ENGINE_finish
(impl);
183
return
0;
184
}
185
/* We'll use the ENGINE's private digest definition */
186
type = d;
187
/* Store the ENGINE functional reference so we know
188
* 'type' came from an ENGINE and we need to release
189
* it when done. */
190
ctx->
engine
= impl;
191
}
192
else
193
ctx->
engine
= NULL;
194
}
195
else
196
if
(!ctx->
digest
)
197
{
198
EVPerr
(
EVP_F_EVP_DIGESTINIT_EX
,
EVP_R_NO_DIGEST_SET
);
199
return
0;
200
}
201
#endif
202
if
(ctx->
digest
!= type)
203
{
204
if
(ctx->
digest
&& ctx->
digest
->
ctx_size
)
205
OPENSSL_free
(ctx->
md_data
);
206
ctx->
digest
=
type
;
207
if
(!(ctx->
flags
&
EVP_MD_CTX_FLAG_NO_INIT
) && type->
ctx_size
)
208
{
209
ctx->
update
= type->
update
;
210
ctx->
md_data
=
OPENSSL_malloc
(type->
ctx_size
);
211
if
(ctx->
md_data
== NULL)
212
{
213
EVPerr
(
EVP_F_EVP_DIGESTINIT_EX
,
214
ERR_R_MALLOC_FAILURE
);
215
return
0;
216
}
217
}
218
}
219
#ifndef OPENSSL_NO_ENGINE
220
skip_to_init:
221
#endif
222
if
(ctx->
pctx
)
223
{
224
int
r;
225
r =
EVP_PKEY_CTX_ctrl
(ctx->
pctx
, -1,
EVP_PKEY_OP_TYPE_SIG
,
226
EVP_PKEY_CTRL_DIGESTINIT
, 0, ctx);
227
if
(r <= 0 && (r != -2))
228
return
0;
229
}
230
if
(ctx->
flags
&
EVP_MD_CTX_FLAG_NO_INIT
)
231
return
1;
232
#ifdef OPENSSL_FIPS
233
if
(
FIPS_mode
())
234
{
235
if
(FIPS_digestinit(ctx, type))
236
return
1;
237
OPENSSL_free
(ctx->
md_data
);
238
ctx->
md_data
= NULL;
239
return
0;
240
}
241
#endif
242
return
ctx->
digest
->
init
(ctx);
243
}
244
245
int
EVP_DigestUpdate
(
EVP_MD_CTX
*ctx,
const
void
*
data
,
size_t
count)
246
{
247
#ifdef OPENSSL_FIPS
248
return
FIPS_digestupdate(ctx, data, count);
249
#else
250
return
ctx->
update
(ctx,data,count);
251
#endif
252
}
253
254
/* The caller can assume that this removes any secret data from the context */
255
int
EVP_DigestFinal
(
EVP_MD_CTX
*ctx,
unsigned
char
*md,
unsigned
int
*size)
256
{
257
int
ret;
258
ret =
EVP_DigestFinal_ex
(ctx, md, size);
259
EVP_MD_CTX_cleanup
(ctx);
260
return
ret;
261
}
262
263
/* The caller can assume that this removes any secret data from the context */
264
int
EVP_DigestFinal_ex
(
EVP_MD_CTX
*ctx,
unsigned
char
*md,
unsigned
int
*size)
265
{
266
#ifdef OPENSSL_FIPS
267
return
FIPS_digestfinal(ctx, md, size);
268
#else
269
int
ret;
270
OPENSSL_assert
(ctx->
digest
->
md_size
<=
EVP_MAX_MD_SIZE
);
271
ret=ctx->
digest
->
final
(ctx,md);
272
if
(size != NULL)
273
*size=ctx->
digest
->
md_size
;
274
if
(ctx->
digest
->
cleanup
)
275
{
276
ctx->
digest
->
cleanup
(ctx);
277
EVP_MD_CTX_set_flags
(ctx,
EVP_MD_CTX_FLAG_CLEANED
);
278
}
279
memset(ctx->
md_data
,0,ctx->
digest
->
ctx_size
);
280
return
ret;
281
#endif
282
}
283
284
int
EVP_MD_CTX_copy
(
EVP_MD_CTX
*out,
const
EVP_MD_CTX
*in)
285
{
286
EVP_MD_CTX_init
(out);
287
return
EVP_MD_CTX_copy_ex
(out, in);
288
}
289
290
int
EVP_MD_CTX_copy_ex
(
EVP_MD_CTX
*out,
const
EVP_MD_CTX
*in)
291
{
292
unsigned
char
*tmp_buf;
293
if
((in == NULL) || (in->
digest
== NULL))
294
{
295
EVPerr
(
EVP_F_EVP_MD_CTX_COPY_EX
,
EVP_R_INPUT_NOT_INITIALIZED
);
296
return
0;
297
}
298
#ifndef OPENSSL_NO_ENGINE
299
/* Make sure it's safe to copy a digest context using an ENGINE */
300
if
(in->
engine
&& !
ENGINE_init
(in->
engine
))
301
{
302
EVPerr
(
EVP_F_EVP_MD_CTX_COPY_EX
,
ERR_R_ENGINE_LIB
);
303
return
0;
304
}
305
#endif
306
307
if
(out->
digest
== in->
digest
)
308
{
309
tmp_buf = out->
md_data
;
310
EVP_MD_CTX_set_flags
(out,
EVP_MD_CTX_FLAG_REUSE
);
311
}
312
else
tmp_buf = NULL;
313
EVP_MD_CTX_cleanup
(out);
314
memcpy(out,in,
sizeof
*out);
315
316
if
(in->
md_data
&& out->
digest
->
ctx_size
)
317
{
318
if
(tmp_buf)
319
out->
md_data
= tmp_buf;
320
else
321
{
322
out->
md_data
=
OPENSSL_malloc
(out->
digest
->
ctx_size
);
323
if
(!out->
md_data
)
324
{
325
EVPerr
(
EVP_F_EVP_MD_CTX_COPY_EX
,
ERR_R_MALLOC_FAILURE
);
326
return
0;
327
}
328
}
329
memcpy(out->
md_data
,in->
md_data
,out->
digest
->
ctx_size
);
330
}
331
332
out->
update
= in->
update
;
333
334
if
(in->
pctx
)
335
{
336
out->
pctx
=
EVP_PKEY_CTX_dup
(in->
pctx
);
337
if
(!out->
pctx
)
338
{
339
EVP_MD_CTX_cleanup
(out);
340
return
0;
341
}
342
}
343
344
if
(out->
digest
->
copy
)
345
return
out->
digest
->
copy
(out,in);
346
347
return
1;
348
}
349
350
int
EVP_Digest
(
const
void
*
data
,
size_t
count,
351
unsigned
char
*md,
unsigned
int
*size,
const
EVP_MD
*
type
,
ENGINE
*impl)
352
{
353
EVP_MD_CTX
ctx;
354
int
ret;
355
356
EVP_MD_CTX_init
(&ctx);
357
EVP_MD_CTX_set_flags
(&ctx,
EVP_MD_CTX_FLAG_ONESHOT
);
358
ret=
EVP_DigestInit_ex
(&ctx, type, impl)
359
&&
EVP_DigestUpdate
(&ctx, data, count)
360
&&
EVP_DigestFinal_ex
(&ctx, md, size);
361
EVP_MD_CTX_cleanup
(&ctx);
362
363
return
ret;
364
}
365
366
void
EVP_MD_CTX_destroy
(
EVP_MD_CTX
*ctx)
367
{
368
EVP_MD_CTX_cleanup
(ctx);
369
OPENSSL_free
(ctx);
370
}
371
372
/* This call frees resources associated with the context */
373
int
EVP_MD_CTX_cleanup
(
EVP_MD_CTX
*ctx)
374
{
375
#ifndef OPENSSL_FIPS
376
/* Don't assume ctx->md_data was cleaned in EVP_Digest_Final,
377
* because sometimes only copies of the context are ever finalised.
378
*/
379
if
(ctx->
digest
&& ctx->
digest
->
cleanup
380
&& !
EVP_MD_CTX_test_flags
(ctx,
EVP_MD_CTX_FLAG_CLEANED
))
381
ctx->
digest
->
cleanup
(ctx);
382
if
(ctx->
digest
&& ctx->
digest
->
ctx_size
&& ctx->
md_data
383
&& !
EVP_MD_CTX_test_flags
(ctx,
EVP_MD_CTX_FLAG_REUSE
))
384
{
385
OPENSSL_cleanse
(ctx->
md_data
,ctx->
digest
->
ctx_size
);
386
OPENSSL_free
(ctx->
md_data
);
387
}
388
#endif
389
if
(ctx->
pctx
)
390
EVP_PKEY_CTX_free
(ctx->
pctx
);
391
#ifndef OPENSSL_NO_ENGINE
392
if
(ctx->
engine
)
393
/* The EVP_MD we used belongs to an ENGINE, release the
394
* functional reference we held for this reason. */
395
ENGINE_finish
(ctx->
engine
);
396
#endif
397
#ifdef OPENSSL_FIPS
398
FIPS_md_ctx_cleanup(ctx);
399
#endif
400
memset(ctx,
'\0'
,
sizeof
*ctx);
401
402
return
1;
403
}
Generated on Thu Jan 10 2013 09:53:36 for OpenSSL by
1.8.2