diff options
Diffstat (limited to 'src/lib/libcrypto/evp/digest.c')
| -rw-r--r-- | src/lib/libcrypto/evp/digest.c | 154 |
1 files changed, 130 insertions, 24 deletions
diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c index 762e6d3450..3bc2d1295c 100644 --- a/src/lib/libcrypto/evp/digest.c +++ b/src/lib/libcrypto/evp/digest.c | |||
| @@ -116,6 +116,7 @@ | |||
| 116 | #ifndef OPENSSL_NO_ENGINE | 116 | #ifndef OPENSSL_NO_ENGINE |
| 117 | #include <openssl/engine.h> | 117 | #include <openssl/engine.h> |
| 118 | #endif | 118 | #endif |
| 119 | #include "evp_locl.h" | ||
| 119 | 120 | ||
| 120 | void EVP_MD_CTX_init(EVP_MD_CTX *ctx) | 121 | void EVP_MD_CTX_init(EVP_MD_CTX *ctx) |
| 121 | { | 122 | { |
| @@ -137,18 +138,77 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) | |||
| 137 | return EVP_DigestInit_ex(ctx, type, NULL); | 138 | return EVP_DigestInit_ex(ctx, type, NULL); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 140 | int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) | 141 | #ifdef OPENSSL_FIPS |
| 142 | |||
| 143 | /* The purpose of these is to trap programs that attempt to use non FIPS | ||
| 144 | * algorithms in FIPS mode and ignore the errors. | ||
| 145 | */ | ||
| 146 | |||
| 147 | static int bad_init(EVP_MD_CTX *ctx) | ||
| 148 | { FIPS_ERROR_IGNORED("Digest init"); return 0;} | ||
| 149 | |||
| 150 | static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count) | ||
| 151 | { FIPS_ERROR_IGNORED("Digest update"); return 0;} | ||
| 152 | |||
| 153 | static int bad_final(EVP_MD_CTX *ctx,unsigned char *md) | ||
| 154 | { FIPS_ERROR_IGNORED("Digest Final"); return 0;} | ||
| 155 | |||
| 156 | static const EVP_MD bad_md = | ||
| 141 | { | 157 | { |
| 142 | EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); | 158 | 0, |
| 159 | 0, | ||
| 160 | 0, | ||
| 161 | 0, | ||
| 162 | bad_init, | ||
| 163 | bad_update, | ||
| 164 | bad_final, | ||
| 165 | NULL, | ||
| 166 | NULL, | ||
| 167 | NULL, | ||
| 168 | 0, | ||
| 169 | {0,0,0,0}, | ||
| 170 | }; | ||
| 171 | |||
| 172 | #endif | ||
| 173 | |||
| 143 | #ifndef OPENSSL_NO_ENGINE | 174 | #ifndef OPENSSL_NO_ENGINE |
| 144 | /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts | 175 | |
| 145 | * so this context may already have an ENGINE! Try to avoid releasing | 176 | #ifdef OPENSSL_FIPS |
| 146 | * the previous handle, re-querying for an ENGINE, and having a | 177 | |
| 147 | * reinitialisation, when it may all be unecessary. */ | 178 | static int do_engine_null(ENGINE *impl) { return 0;} |
| 148 | if (ctx->engine && ctx->digest && (!type || | 179 | static int do_evp_md_engine_null(EVP_MD_CTX *ctx, |
| 149 | (type && (type->type == ctx->digest->type)))) | 180 | const EVP_MD **ptype, ENGINE *impl) |
| 150 | goto skip_to_init; | 181 | { return 1; } |
| 151 | if (type) | 182 | |
| 183 | static int (*do_engine_init)(ENGINE *impl) | ||
| 184 | = do_engine_null; | ||
| 185 | |||
| 186 | static int (*do_engine_finish)(ENGINE *impl) | ||
| 187 | = do_engine_null; | ||
| 188 | |||
| 189 | static int (*do_evp_md_engine) | ||
| 190 | (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) | ||
| 191 | = do_evp_md_engine_null; | ||
| 192 | |||
| 193 | void int_EVP_MD_set_engine_callbacks( | ||
| 194 | int (*eng_md_init)(ENGINE *impl), | ||
| 195 | int (*eng_md_fin)(ENGINE *impl), | ||
| 196 | int (*eng_md_evp) | ||
| 197 | (EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)) | ||
| 198 | { | ||
| 199 | do_engine_init = eng_md_init; | ||
| 200 | do_engine_finish = eng_md_fin; | ||
| 201 | do_evp_md_engine = eng_md_evp; | ||
| 202 | } | ||
| 203 | |||
| 204 | #else | ||
| 205 | |||
| 206 | #define do_engine_init ENGINE_init | ||
| 207 | #define do_engine_finish ENGINE_finish | ||
| 208 | |||
| 209 | static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl) | ||
| 210 | { | ||
| 211 | if (*ptype) | ||
| 152 | { | 212 | { |
| 153 | /* Ensure an ENGINE left lying around from last time is cleared | 213 | /* Ensure an ENGINE left lying around from last time is cleared |
| 154 | * (the previous check attempted to avoid this if the same | 214 | * (the previous check attempted to avoid this if the same |
| @@ -159,25 +219,25 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) | |||
| 159 | { | 219 | { |
| 160 | if (!ENGINE_init(impl)) | 220 | if (!ENGINE_init(impl)) |
| 161 | { | 221 | { |
| 162 | EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); | 222 | EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); |
| 163 | return 0; | 223 | return 0; |
| 164 | } | 224 | } |
| 165 | } | 225 | } |
| 166 | else | 226 | else |
| 167 | /* Ask if an ENGINE is reserved for this job */ | 227 | /* Ask if an ENGINE is reserved for this job */ |
| 168 | impl = ENGINE_get_digest_engine(type->type); | 228 | impl = ENGINE_get_digest_engine((*ptype)->type); |
| 169 | if(impl) | 229 | if(impl) |
| 170 | { | 230 | { |
| 171 | /* There's an ENGINE for this job ... (apparently) */ | 231 | /* There's an ENGINE for this job ... (apparently) */ |
| 172 | const EVP_MD *d = ENGINE_get_digest(impl, type->type); | 232 | const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type); |
| 173 | if(!d) | 233 | if(!d) |
| 174 | { | 234 | { |
| 175 | /* Same comment from evp_enc.c */ | 235 | /* Same comment from evp_enc.c */ |
| 176 | EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); | 236 | EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR); |
| 177 | return 0; | 237 | return 0; |
| 178 | } | 238 | } |
| 179 | /* We'll use the ENGINE's private digest definition */ | 239 | /* We'll use the ENGINE's private digest definition */ |
| 180 | type = d; | 240 | *ptype = d; |
| 181 | /* Store the ENGINE functional reference so we know | 241 | /* Store the ENGINE functional reference so we know |
| 182 | * 'type' came from an ENGINE and we need to release | 242 | * 'type' came from an ENGINE and we need to release |
| 183 | * it when done. */ | 243 | * it when done. */ |
| @@ -189,12 +249,52 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) | |||
| 189 | else | 249 | else |
| 190 | if(!ctx->digest) | 250 | if(!ctx->digest) |
| 191 | { | 251 | { |
| 192 | EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET); | 252 | EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET); |
| 193 | return 0; | 253 | return 0; |
| 194 | } | 254 | } |
| 255 | return 1; | ||
| 256 | } | ||
| 257 | |||
| 258 | #endif | ||
| 259 | |||
| 260 | #endif | ||
| 261 | |||
| 262 | int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) | ||
| 263 | { | ||
| 264 | M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); | ||
| 265 | #ifdef OPENSSL_FIPS | ||
| 266 | if(FIPS_selftest_failed()) | ||
| 267 | { | ||
| 268 | FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED); | ||
| 269 | ctx->digest = &bad_md; | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | #endif | ||
| 273 | #ifndef OPENSSL_NO_ENGINE | ||
| 274 | /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts | ||
| 275 | * so this context may already have an ENGINE! Try to avoid releasing | ||
| 276 | * the previous handle, re-querying for an ENGINE, and having a | ||
| 277 | * reinitialisation, when it may all be unecessary. */ | ||
| 278 | if (ctx->engine && ctx->digest && (!type || | ||
| 279 | (type && (type->type == ctx->digest->type)))) | ||
| 280 | goto skip_to_init; | ||
| 281 | if (!do_evp_md_engine(ctx, &type, impl)) | ||
| 282 | return 0; | ||
| 195 | #endif | 283 | #endif |
| 196 | if (ctx->digest != type) | 284 | if (ctx->digest != type) |
| 197 | { | 285 | { |
| 286 | #ifdef OPENSSL_FIPS | ||
| 287 | if (FIPS_mode()) | ||
| 288 | { | ||
| 289 | if (!(type->flags & EVP_MD_FLAG_FIPS) | ||
| 290 | && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) | ||
| 291 | { | ||
| 292 | EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS); | ||
| 293 | ctx->digest = &bad_md; | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | #endif | ||
| 198 | if (ctx->digest && ctx->digest->ctx_size) | 298 | if (ctx->digest && ctx->digest->ctx_size) |
| 199 | OPENSSL_free(ctx->md_data); | 299 | OPENSSL_free(ctx->md_data); |
| 200 | ctx->digest=type; | 300 | ctx->digest=type; |
| @@ -202,7 +302,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) | |||
| 202 | ctx->md_data=OPENSSL_malloc(type->ctx_size); | 302 | ctx->md_data=OPENSSL_malloc(type->ctx_size); |
| 203 | } | 303 | } |
| 204 | #ifndef OPENSSL_NO_ENGINE | 304 | #ifndef OPENSSL_NO_ENGINE |
| 205 | skip_to_init: | 305 | skip_to_init: |
| 206 | #endif | 306 | #endif |
| 207 | return ctx->digest->init(ctx); | 307 | return ctx->digest->init(ctx); |
| 208 | } | 308 | } |
| @@ -210,6 +310,9 @@ skip_to_init: | |||
| 210 | int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, | 310 | int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, |
| 211 | size_t count) | 311 | size_t count) |
| 212 | { | 312 | { |
| 313 | #ifdef OPENSSL_FIPS | ||
| 314 | FIPS_selftest_check(); | ||
| 315 | #endif | ||
| 213 | return ctx->digest->update(ctx,data,count); | 316 | return ctx->digest->update(ctx,data,count); |
| 214 | } | 317 | } |
| 215 | 318 | ||
| @@ -226,6 +329,9 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) | |||
| 226 | int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) | 329 | int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) |
| 227 | { | 330 | { |
| 228 | int ret; | 331 | int ret; |
| 332 | #ifdef OPENSSL_FIPS | ||
| 333 | FIPS_selftest_check(); | ||
| 334 | #endif | ||
| 229 | 335 | ||
| 230 | OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); | 336 | OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); |
| 231 | ret=ctx->digest->final(ctx,md); | 337 | ret=ctx->digest->final(ctx,md); |
| @@ -234,7 +340,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) | |||
| 234 | if (ctx->digest->cleanup) | 340 | if (ctx->digest->cleanup) |
| 235 | { | 341 | { |
| 236 | ctx->digest->cleanup(ctx); | 342 | ctx->digest->cleanup(ctx); |
| 237 | EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); | 343 | M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); |
| 238 | } | 344 | } |
| 239 | memset(ctx->md_data,0,ctx->digest->ctx_size); | 345 | memset(ctx->md_data,0,ctx->digest->ctx_size); |
| 240 | return ret; | 346 | return ret; |
| @@ -256,7 +362,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) | |||
| 256 | } | 362 | } |
| 257 | #ifndef OPENSSL_NO_ENGINE | 363 | #ifndef OPENSSL_NO_ENGINE |
| 258 | /* Make sure it's safe to copy a digest context using an ENGINE */ | 364 | /* Make sure it's safe to copy a digest context using an ENGINE */ |
| 259 | if (in->engine && !ENGINE_init(in->engine)) | 365 | if (in->engine && !do_engine_init(in->engine)) |
| 260 | { | 366 | { |
| 261 | EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB); | 367 | EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB); |
| 262 | return 0; | 368 | return 0; |
| @@ -266,7 +372,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) | |||
| 266 | if (out->digest == in->digest) | 372 | if (out->digest == in->digest) |
| 267 | { | 373 | { |
| 268 | tmp_buf = out->md_data; | 374 | tmp_buf = out->md_data; |
| 269 | EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); | 375 | M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE); |
| 270 | } | 376 | } |
| 271 | else tmp_buf = NULL; | 377 | else tmp_buf = NULL; |
| 272 | EVP_MD_CTX_cleanup(out); | 378 | EVP_MD_CTX_cleanup(out); |
| @@ -292,7 +398,7 @@ int EVP_Digest(const void *data, size_t count, | |||
| 292 | int ret; | 398 | int ret; |
| 293 | 399 | ||
| 294 | EVP_MD_CTX_init(&ctx); | 400 | EVP_MD_CTX_init(&ctx); |
| 295 | EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); | 401 | M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT); |
| 296 | ret=EVP_DigestInit_ex(&ctx, type, impl) | 402 | ret=EVP_DigestInit_ex(&ctx, type, impl) |
| 297 | && EVP_DigestUpdate(&ctx, data, count) | 403 | && EVP_DigestUpdate(&ctx, data, count) |
| 298 | && EVP_DigestFinal_ex(&ctx, md, size); | 404 | && EVP_DigestFinal_ex(&ctx, md, size); |
| @@ -314,10 +420,10 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) | |||
| 314 | * because sometimes only copies of the context are ever finalised. | 420 | * because sometimes only copies of the context are ever finalised. |
| 315 | */ | 421 | */ |
| 316 | if (ctx->digest && ctx->digest->cleanup | 422 | if (ctx->digest && ctx->digest->cleanup |
| 317 | && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) | 423 | && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED)) |
| 318 | ctx->digest->cleanup(ctx); | 424 | ctx->digest->cleanup(ctx); |
| 319 | if (ctx->digest && ctx->digest->ctx_size && ctx->md_data | 425 | if (ctx->digest && ctx->digest->ctx_size && ctx->md_data |
| 320 | && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) | 426 | && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) |
| 321 | { | 427 | { |
| 322 | OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); | 428 | OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size); |
| 323 | OPENSSL_free(ctx->md_data); | 429 | OPENSSL_free(ctx->md_data); |
| @@ -326,7 +432,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) | |||
| 326 | if(ctx->engine) | 432 | if(ctx->engine) |
| 327 | /* The EVP_MD we used belongs to an ENGINE, release the | 433 | /* The EVP_MD we used belongs to an ENGINE, release the |
| 328 | * functional reference we held for this reason. */ | 434 | * functional reference we held for this reason. */ |
| 329 | ENGINE_finish(ctx->engine); | 435 | do_engine_finish(ctx->engine); |
| 330 | #endif | 436 | #endif |
| 331 | memset(ctx,'\0',sizeof *ctx); | 437 | memset(ctx,'\0',sizeof *ctx); |
| 332 | 438 | ||
