Home | History | Annotate | Download | only in digest
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 
     78 static void md4_init(EVP_MD_CTX *ctx) {
     79   CHECK(MD4_Init(ctx->md_data));
     80 }
     81 
     82 static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
     83   CHECK(MD4_Update(ctx->md_data, data, count));
     84 }
     85 
     86 static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) {
     87   CHECK(MD4_Final(out, ctx->md_data));
     88 }
     89 
     90 DEFINE_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 
    102 static void md5_init(EVP_MD_CTX *ctx) {
    103   CHECK(MD5_Init(ctx->md_data));
    104 }
    105 
    106 static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
    107   CHECK(MD5_Update(ctx->md_data, data, count));
    108 }
    109 
    110 static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) {
    111   CHECK(MD5_Final(out, ctx->md_data));
    112 }
    113 
    114 DEFINE_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 
    126 static void sha1_init(EVP_MD_CTX *ctx) {
    127   CHECK(SHA1_Init(ctx->md_data));
    128 }
    129 
    130 static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
    131   CHECK(SHA1_Update(ctx->md_data, data, count));
    132 }
    133 
    134 static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) {
    135   CHECK(SHA1_Final(md, ctx->md_data));
    136 }
    137 
    138 DEFINE_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 
    150 static void sha224_init(EVP_MD_CTX *ctx) {
    151   CHECK(SHA224_Init(ctx->md_data));
    152 }
    153 
    154 static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
    155   CHECK(SHA224_Update(ctx->md_data, data, count));
    156 }
    157 
    158 static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) {
    159   CHECK(SHA224_Final(md, ctx->md_data));
    160 }
    161 
    162 DEFINE_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 
    174 static void sha256_init(EVP_MD_CTX *ctx) {
    175   CHECK(SHA256_Init(ctx->md_data));
    176 }
    177 
    178 static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
    179   CHECK(SHA256_Update(ctx->md_data, data, count));
    180 }
    181 
    182 static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) {
    183   CHECK(SHA256_Final(md, ctx->md_data));
    184 }
    185 
    186 DEFINE_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 
    198 static void sha384_init(EVP_MD_CTX *ctx) {
    199   CHECK(SHA384_Init(ctx->md_data));
    200 }
    201 
    202 static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
    203   CHECK(SHA384_Update(ctx->md_data, data, count));
    204 }
    205 
    206 static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) {
    207   CHECK(SHA384_Final(md, ctx->md_data));
    208 }
    209 
    210 DEFINE_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 
    222 static void sha512_init(EVP_MD_CTX *ctx) {
    223   CHECK(SHA512_Init(ctx->md_data));
    224 }
    225 
    226 static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
    227   CHECK(SHA512_Update(ctx->md_data, data, count));
    228 }
    229 
    230 static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) {
    231   CHECK(SHA512_Final(md, ctx->md_data));
    232 }
    233 
    234 DEFINE_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 
    246 typedef struct {
    247   MD5_CTX md5;
    248   SHA_CTX sha1;
    249 } MD5_SHA1_CTX;
    250 
    251 static 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 
    256 static 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 
    263 static 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 
    269 DEFINE_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