LCOV - code coverage report
Current view: top level - openssh-6.6p1 - digest-openssl.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 45 47 95.7 %
Date: 2014-08-01 Functions: 10 10 100.0 %
Branches: 22 44 50.0 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: digest-openssl.c,v 1.2 2014/02/02 03:44:31 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Copyright (c) 2013 Damien Miller <djm@mindrot.org>
       4                 :            :  *
       5                 :            :  * Permission to use, copy, modify, and distribute this software for any
       6                 :            :  * purpose with or without fee is hereby granted, provided that the above
       7                 :            :  * copyright notice and this permission notice appear in all copies.
       8                 :            :  *
       9                 :            :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      10                 :            :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11                 :            :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      12                 :            :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13                 :            :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14                 :            :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      15                 :            :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16                 :            :  */
      17                 :            : 
      18                 :            : #include "includes.h"
      19                 :            : 
      20                 :            : #include <sys/types.h>
      21                 :            : #include <limits.h>
      22                 :            : #include <stdlib.h>
      23                 :            : #include <string.h>
      24                 :            : 
      25                 :            : #include <openssl/evp.h>
      26                 :            : 
      27                 :            : #include "openbsd-compat/openssl-compat.h"
      28                 :            : 
      29                 :            : #include "buffer.h"
      30                 :            : #include "digest.h"
      31                 :            : 
      32                 :            : struct ssh_digest_ctx {
      33                 :            :         int alg;
      34                 :            :         EVP_MD_CTX mdctx;
      35                 :            : };
      36                 :            : 
      37                 :            : struct ssh_digest {
      38                 :            :         int id;
      39                 :            :         const char *name;
      40                 :            :         size_t digest_len;
      41                 :            :         const EVP_MD *(*mdfunc)(void);
      42                 :            : };
      43                 :            : 
      44                 :            : /* NB. Indexed directly by algorithm number */
      45                 :            : const struct ssh_digest digests[] = {
      46                 :            :         { SSH_DIGEST_MD5,       "MD5",                16,     EVP_md5 },
      47                 :            :         { SSH_DIGEST_RIPEMD160, "RIPEMD160",  20,     EVP_ripemd160 },
      48                 :            :         { SSH_DIGEST_SHA1,      "SHA1",               20,     EVP_sha1 },
      49                 :            : #ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */
      50                 :            :         { SSH_DIGEST_SHA256,    "SHA256",     32,     EVP_sha256 },
      51                 :            :         { SSH_DIGEST_SHA384,    "SHA384",     48,     EVP_sha384 },
      52                 :            :         { SSH_DIGEST_SHA512,    "SHA512",     64,     EVP_sha512 },
      53                 :            : #endif
      54                 :            :         { -1,                   NULL,           0,      NULL },
      55                 :            : };
      56                 :            : 
      57                 :            : static const struct ssh_digest *
      58                 :            : ssh_digest_by_alg(int alg)
      59                 :            : {
      60 [ +  - ][ +  - ]:     195510 :         if (alg < 0 || alg >= SSH_DIGEST_MAX)
                 [ +  - ]
      61                 :            :                 return NULL;
      62 [ +  - ][ +  - ]:     195510 :         if (digests[alg].id != alg) /* sanity */
                 [ +  - ]
      63                 :            :                 return NULL;
      64                 :     195510 :         return &(digests[alg]);
      65                 :            : }
      66                 :            : 
      67                 :            : size_t
      68                 :      61896 : ssh_digest_bytes(int alg)
      69                 :            : {
      70                 :      61896 :         const struct ssh_digest *digest = ssh_digest_by_alg(alg);
      71                 :            : 
      72         [ +  - ]:      61896 :         return digest == NULL ? 0 : digest->digest_len;
      73                 :            : }
      74                 :            : 
      75                 :            : size_t
      76                 :       4238 : ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
      77                 :            : {
      78                 :       4238 :         return EVP_MD_CTX_block_size(&ctx->mdctx);
      79                 :            : }
      80                 :            : 
      81                 :            : struct ssh_digest_ctx *
      82                 :      40380 : ssh_digest_start(int alg)
      83                 :            : {
      84                 :      40380 :         const struct ssh_digest *digest = ssh_digest_by_alg(alg);
      85                 :            :         struct ssh_digest_ctx *ret;
      86                 :            : 
      87 [ +  - ][ +  - ]:      40380 :         if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
      88                 :            :                 return NULL;
      89                 :      40380 :         ret->alg = alg;
      90                 :      40380 :         EVP_MD_CTX_init(&ret->mdctx);
      91         [ -  + ]:      40380 :         if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
      92                 :          0 :                 free(ret);
      93                 :          0 :                 return NULL;
      94                 :            :         }
      95                 :            :         return ret;
      96                 :            : }
      97                 :            : 
      98                 :            : int
      99                 :      69776 : ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
     100                 :            : {
     101                 :            :         /* we have bcopy-style order while openssl has memcpy-style */
     102         [ +  - ]:      69776 :         if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
     103                 :            :                 return -1;
     104                 :      69776 :         return 0;
     105                 :            : }
     106                 :            : 
     107                 :            : int
     108                 :     143585 : ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
     109                 :            : {
     110 [ +  - ][ +  - ]:     170925 :         if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
                 [ +  - ]
     111                 :            :                 return -1;
     112                 :     143585 :         return 0;
     113                 :            : }
     114                 :            : 
     115                 :            : int
     116                 :      12384 : ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
     117                 :            : {
     118                 :      12384 :         return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
     119                 :            : }
     120                 :            : 
     121                 :            : int
     122                 :      93234 : ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
     123                 :            : {
     124                 :     186468 :         const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
     125                 :      93234 :         u_int l = dlen;
     126                 :            : 
     127         [ +  - ]:      93234 :         if (dlen > UINT_MAX)
     128                 :            :                 return -1;
     129         [ +  - ]:      93234 :         if (dlen < digest->digest_len) /* No truncation allowed */
     130                 :            :                 return -1;
     131         [ +  - ]:      93234 :         if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
     132                 :            :                 return -1;
     133         [ +  - ]:      93234 :         if (l != digest->digest_len) /* sanity */
     134                 :            :                 return -1;
     135                 :      93234 :         return 0;
     136                 :            : }
     137                 :            : 
     138                 :            : void
     139                 :      29397 : ssh_digest_free(struct ssh_digest_ctx *ctx)
     140                 :            : {
     141         [ +  - ]:      29397 :         if (ctx != NULL) {
     142                 :      29397 :                 EVP_MD_CTX_cleanup(&ctx->mdctx);
     143                 :      29397 :                 explicit_bzero(ctx, sizeof(*ctx));
     144                 :      29397 :                 free(ctx);
     145                 :            :         }
     146                 :      29397 : }
     147                 :            : 
     148                 :            : int
     149                 :      14956 : ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
     150                 :            : {
     151                 :      14956 :         struct ssh_digest_ctx *ctx = ssh_digest_start(alg);
     152                 :            : 
     153         [ +  - ]:      14956 :         if (ctx == NULL)
     154                 :            :                 return -1;
     155   [ +  -  +  - ]:      29912 :         if (ssh_digest_update(ctx, m, mlen) != 0 ||
     156                 :      14956 :             ssh_digest_final(ctx, d, dlen) != 0)
     157                 :            :                 return -1;
     158                 :      14956 :         ssh_digest_free(ctx);
     159                 :      14956 :         return 0;
     160                 :            : }
     161                 :            : 
     162                 :            : int
     163                 :       1872 : ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
     164                 :            : {
     165                 :       1872 :         return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
     166                 :            : }

Generated by: LCOV version 1.9