LCOV - code coverage report
Current view: top level - openssh-6.6p1 - ssh-ed25519.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 51 73 69.9 %
Date: 2014-08-01 Functions: 2 2 100.0 %
Branches: 19 38 50.0 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: ssh-ed25519.c,v 1.3 2014/02/23 20:03:42 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Copyright (c) 2013 Markus Friedl <markus@openbsd.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                 :            : 
      22                 :            : #include "crypto_api.h"
      23                 :            : 
      24                 :            : #include <limits.h>
      25                 :            : #include <string.h>
      26                 :            : #include <stdarg.h>
      27                 :            : 
      28                 :            : #include "xmalloc.h"
      29                 :            : #include "log.h"
      30                 :            : #include "buffer.h"
      31                 :            : #include "key.h"
      32                 :            : #include "ssh.h"
      33                 :            : 
      34                 :            : int
      35                 :         25 : ssh_ed25519_sign(const Key *key, u_char **sigp, u_int *lenp,
      36                 :            :     const u_char *data, u_int datalen)
      37                 :            : {
      38                 :            :         u_char *sig;
      39                 :            :         u_int slen, len;
      40                 :            :         unsigned long long smlen;
      41                 :            :         int ret;
      42                 :            :         Buffer b;
      43                 :            : 
      44 [ +  - ][ +  - ]:         25 :         if (key == NULL || key_type_plain(key->type) != KEY_ED25519 ||
                 [ -  + ]
      45                 :         25 :             key->ed25519_sk == NULL) {
      46                 :          0 :                 error("%s: no ED25519 key", __func__);
      47                 :          0 :                 return -1;
      48                 :            :         }
      49                 :            : 
      50         [ -  + ]:         25 :         if (datalen >= UINT_MAX - crypto_sign_ed25519_BYTES) {
      51                 :          0 :                 error("%s: datalen %u too long", __func__, datalen);
      52                 :          0 :                 return -1;
      53                 :            :         }
      54                 :         25 :         smlen = slen = datalen + crypto_sign_ed25519_BYTES;
      55                 :         25 :         sig = xmalloc(slen);
      56                 :            : 
      57         [ +  - ]:         25 :         if ((ret = crypto_sign_ed25519(sig, &smlen, data, datalen,
      58         [ -  + ]:         25 :             key->ed25519_sk)) != 0 || smlen <= datalen) {
      59                 :          0 :                 error("%s: crypto_sign_ed25519 failed: %d", __func__, ret);
      60                 :          0 :                 free(sig);
      61                 :          0 :                 return -1;
      62                 :            :         }
      63                 :            :         /* encode signature */
      64                 :         25 :         buffer_init(&b);
      65                 :         25 :         buffer_put_cstring(&b, "ssh-ed25519");
      66                 :         25 :         buffer_put_string(&b, sig, smlen - datalen);
      67                 :         25 :         len = buffer_len(&b);
      68         [ +  - ]:         25 :         if (lenp != NULL)
      69                 :         25 :                 *lenp = len;
      70         [ +  - ]:         25 :         if (sigp != NULL) {
      71                 :         25 :                 *sigp = xmalloc(len);
      72                 :         25 :                 memcpy(*sigp, buffer_ptr(&b), len);
      73                 :            :         }
      74                 :         25 :         buffer_free(&b);
      75                 :         25 :         explicit_bzero(sig, slen);
      76                 :         25 :         free(sig);
      77                 :            : 
      78                 :         25 :         return 0;
      79                 :            : }
      80                 :            : 
      81                 :            : int
      82                 :         28 : ssh_ed25519_verify(const Key *key, const u_char *signature, u_int signaturelen,
      83                 :            :     const u_char *data, u_int datalen)
      84                 :            : {
      85                 :            :         Buffer b;
      86                 :            :         char *ktype;
      87                 :            :         u_char *sigblob, *sm, *m;
      88                 :            :         u_int len;
      89                 :            :         unsigned long long smlen, mlen;
      90                 :            :         int rlen, ret;
      91                 :            : 
      92 [ +  - ][ +  - ]:         28 :         if (key == NULL || key_type_plain(key->type) != KEY_ED25519 ||
                 [ -  + ]
      93                 :         28 :             key->ed25519_pk == NULL) {
      94                 :          0 :                 error("%s: no ED25519 key", __func__);
      95                 :          0 :                 return -1;
      96                 :            :         }
      97                 :         28 :         buffer_init(&b);
      98                 :         28 :         buffer_append(&b, signature, signaturelen);
      99                 :         28 :         ktype = buffer_get_cstring(&b, NULL);
     100         [ -  + ]:         28 :         if (strcmp("ssh-ed25519", ktype) != 0) {
     101                 :          0 :                 error("%s: cannot handle type %s", __func__, ktype);
     102                 :          0 :                 buffer_free(&b);
     103                 :          0 :                 free(ktype);
     104                 :          0 :                 return -1;
     105                 :            :         }
     106                 :         28 :         free(ktype);
     107                 :         28 :         sigblob = buffer_get_string(&b, &len);
     108                 :         28 :         rlen = buffer_len(&b);
     109                 :         28 :         buffer_free(&b);
     110         [ -  + ]:         28 :         if (rlen != 0) {
     111                 :          0 :                 error("%s: remaining bytes in signature %d", __func__, rlen);
     112                 :          0 :                 free(sigblob);
     113                 :          0 :                 return -1;
     114                 :            :         }
     115         [ -  + ]:         28 :         if (len > crypto_sign_ed25519_BYTES) {
     116                 :          0 :                 error("%s: len %u > crypto_sign_ed25519_BYTES %u", __func__,
     117                 :            :                     len, crypto_sign_ed25519_BYTES);
     118                 :          0 :                 free(sigblob);
     119                 :          0 :                 return -1;
     120                 :            :         }
     121                 :         28 :         smlen = len + datalen;
     122                 :         28 :         sm = xmalloc(smlen);
     123                 :         28 :         memcpy(sm, sigblob, len);
     124                 :         28 :         memcpy(sm+len, data, datalen);
     125                 :         28 :         mlen = smlen;
     126                 :         28 :         m = xmalloc(mlen);
     127         [ -  + ]:         28 :         if ((ret = crypto_sign_ed25519_open(m, &mlen, sm, smlen,
     128                 :         28 :             key->ed25519_pk)) != 0) {
     129                 :          0 :                 debug2("%s: crypto_sign_ed25519_open failed: %d",
     130                 :            :                     __func__, ret);
     131                 :            :         }
     132 [ +  - ][ -  + ]:         28 :         if (ret == 0 && mlen != datalen) {
     133                 :          0 :                 debug2("%s: crypto_sign_ed25519_open "
     134                 :            :                     "mlen != datalen (%llu != %u)", __func__, mlen, datalen);
     135                 :          0 :                 ret = -1;
     136                 :            :         }
     137                 :            :         /* XXX compare 'm' and 'data' ? */
     138                 :            : 
     139                 :         28 :         explicit_bzero(sigblob, len);
     140                 :         28 :         explicit_bzero(sm, smlen);
     141                 :         28 :         explicit_bzero(m, smlen); /* NB. mlen may be invalid if ret != 0 */
     142                 :         28 :         free(sigblob);
     143                 :         28 :         free(sm);
     144                 :         28 :         free(m);
     145         [ +  - ]:         28 :         debug("%s: signature %scorrect", __func__, (ret != 0) ? "in" : "");
     146                 :            : 
     147                 :            :         /* translate return code carefully */
     148         [ -  + ]:         28 :         return (ret == 0) ? 1 : -1;
     149                 :            : }

Generated by: LCOV version 1.9