1/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay@cryptsoft.com). 6 * The implementation was written so as to conform with Netscapes SSL. 7 * 8 * This library is free for commercial and non-commercial use as long as 9 * the following conditions are aheared to. The following conditions 10 * apply to all code found in this distribution, be it the RC4, RSA, 11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * included with this distribution is covered by the same copyright terms 13 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * 15 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * the code are not to be removed. 17 * If this package is used in a product, Eric Young should be given attribution 18 * as the author of the parts of the library used. 19 * This can be in the form of a textual message at program startup or 20 * in documentation (online or textual) provided with the package. 21 * 22 * Redistribution and use in source and binary forms, with or without 23 * modification, are permitted provided that the following conditions 24 * are met: 25 * 1. Redistributions of source code must retain the copyright 26 * notice, this list of conditions and the following disclaimer. 27 * 2. Redistributions in binary form must reproduce the above copyright 28 * notice, this list of conditions and the following disclaimer in the 29 * documentation and/or other materials provided with the distribution. 30 * 3. All advertising materials mentioning features or use of this software 31 * must display the following acknowledgement: 32 * "This product includes cryptographic software written by 33 * Eric Young (eay@cryptsoft.com)" 34 * The word 'cryptographic' can be left out if the rouines from the library 35 * being used are not cryptographic related :-). 36 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * the apps directory (application code) you must include an acknowledgement: 38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * SUCH DAMAGE. 51 * 52 * The licence and distribution terms for any publically available version or 53 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * copied and put under another distribution licence 55 * [including the GNU Public Licence.] */ 56 57#include <openssl/digest.h> 58 59#include <assert.h> 60#include <string.h> 61 62#include <openssl/md4.h> 63#include <openssl/md5.h> 64#include <openssl/nid.h> 65#include <openssl/sha.h> 66 67#include "internal.h" 68#include "../delocate.h" 69#include "../../internal.h" 70 71#if defined(NDEBUG) 72#define CHECK(x) (void) (x) 73#else 74#define CHECK(x) assert(x) 75#endif 76 77 78static void md4_init(EVP_MD_CTX *ctx) { 79 CHECK(MD4_Init(ctx->md_data)); 80} 81 82static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 83 CHECK(MD4_Update(ctx->md_data, data, count)); 84} 85 86static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) { 87 CHECK(MD4_Final(out, ctx->md_data)); 88} 89 90DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { 91 out->type = NID_md4; 92 out->md_size = MD4_DIGEST_LENGTH; 93 out->flags = 0; 94 out->init = md4_init; 95 out->update = md4_update; 96 out->final = md4_final; 97 out->block_size = 64; 98 out->ctx_size = sizeof(MD4_CTX); 99} 100 101 102static void md5_init(EVP_MD_CTX *ctx) { 103 CHECK(MD5_Init(ctx->md_data)); 104} 105 106static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 107 CHECK(MD5_Update(ctx->md_data, data, count)); 108} 109 110static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) { 111 CHECK(MD5_Final(out, ctx->md_data)); 112} 113 114DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) { 115 out->type = NID_md5; 116 out->md_size = MD5_DIGEST_LENGTH; 117 out->flags = 0; 118 out->init = md5_init; 119 out->update = md5_update; 120 out->final = md5_final; 121 out->block_size = 64; 122 out->ctx_size = sizeof(MD5_CTX); 123} 124 125 126static void sha1_init(EVP_MD_CTX *ctx) { 127 CHECK(SHA1_Init(ctx->md_data)); 128} 129 130static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 131 CHECK(SHA1_Update(ctx->md_data, data, count)); 132} 133 134static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) { 135 CHECK(SHA1_Final(md, ctx->md_data)); 136} 137 138DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { 139 out->type = NID_sha1; 140 out->md_size = SHA_DIGEST_LENGTH; 141 out->flags = 0; 142 out->init = sha1_init; 143 out->update = sha1_update; 144 out->final = sha1_final; 145 out->block_size = 64; 146 out->ctx_size = sizeof(SHA_CTX); 147} 148 149 150static void sha224_init(EVP_MD_CTX *ctx) { 151 CHECK(SHA224_Init(ctx->md_data)); 152} 153 154static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 155 CHECK(SHA224_Update(ctx->md_data, data, count)); 156} 157 158static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) { 159 CHECK(SHA224_Final(md, ctx->md_data)); 160} 161 162DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { 163 out->type = NID_sha224; 164 out->md_size = SHA224_DIGEST_LENGTH; 165 out->flags = 0; 166 out->init = sha224_init; 167 out->update = sha224_update; 168 out->final = sha224_final; 169 out->block_size = 64; 170 out->ctx_size = sizeof(SHA256_CTX); 171} 172 173 174static void sha256_init(EVP_MD_CTX *ctx) { 175 CHECK(SHA256_Init(ctx->md_data)); 176} 177 178static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 179 CHECK(SHA256_Update(ctx->md_data, data, count)); 180} 181 182static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) { 183 CHECK(SHA256_Final(md, ctx->md_data)); 184} 185 186DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { 187 out->type = NID_sha256; 188 out->md_size = SHA256_DIGEST_LENGTH; 189 out->flags = 0; 190 out->init = sha256_init; 191 out->update = sha256_update; 192 out->final = sha256_final; 193 out->block_size = 64; 194 out->ctx_size = sizeof(SHA256_CTX); 195} 196 197 198static void sha384_init(EVP_MD_CTX *ctx) { 199 CHECK(SHA384_Init(ctx->md_data)); 200} 201 202static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 203 CHECK(SHA384_Update(ctx->md_data, data, count)); 204} 205 206static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) { 207 CHECK(SHA384_Final(md, ctx->md_data)); 208} 209 210DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { 211 out->type = NID_sha384; 212 out->md_size = SHA384_DIGEST_LENGTH; 213 out->flags = 0; 214 out->init = sha384_init; 215 out->update = sha384_update; 216 out->final = sha384_final; 217 out->block_size = 128; 218 out->ctx_size = sizeof(SHA512_CTX); 219} 220 221 222static void sha512_init(EVP_MD_CTX *ctx) { 223 CHECK(SHA512_Init(ctx->md_data)); 224} 225 226static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) { 227 CHECK(SHA512_Update(ctx->md_data, data, count)); 228} 229 230static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) { 231 CHECK(SHA512_Final(md, ctx->md_data)); 232} 233 234DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { 235 out->type = NID_sha512; 236 out->md_size = SHA512_DIGEST_LENGTH; 237 out->flags = 0; 238 out->init = sha512_init; 239 out->update = sha512_update; 240 out->final = sha512_final; 241 out->block_size = 128; 242 out->ctx_size = sizeof(SHA512_CTX); 243} 244 245 246typedef struct { 247 MD5_CTX md5; 248 SHA_CTX sha1; 249} MD5_SHA1_CTX; 250 251static void md5_sha1_init(EVP_MD_CTX *md_ctx) { 252 MD5_SHA1_CTX *ctx = md_ctx->md_data; 253 CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1)); 254} 255 256static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, 257 size_t count) { 258 MD5_SHA1_CTX *ctx = md_ctx->md_data; 259 CHECK(MD5_Update(&ctx->md5, data, count) && 260 SHA1_Update(&ctx->sha1, data, count)); 261} 262 263static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) { 264 MD5_SHA1_CTX *ctx = md_ctx->md_data; 265 CHECK(MD5_Final(out, &ctx->md5) && 266 SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)); 267} 268 269DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) { 270 out->type = NID_md5_sha1; 271 out->md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; 272 out->flags = 0; 273 out->init = md5_sha1_init; 274 out->update = md5_sha1_update; 275 out->final = md5_sha1_final; 276 out->block_size = 64; 277 out->ctx_size = sizeof(MD5_SHA1_CTX); 278} 279 280#undef CHECK 281