Skip to content

Commit

Permalink
- [email protected] 2014/01/09 23:20:00
Browse files Browse the repository at this point in the history
     [digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c]
     [kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c]
     [kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c]
     [schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c]
     Introduce digest API and use it to perform all hashing operations
     rather than calling OpenSSL EVP_Digest* directly. Will make it easier
     to build a reduced-feature OpenSSH without OpenSSL in future;
     feedback, ok markus@
  • Loading branch information
djmdjm committed Jan 9, 2014
1 parent e00e413 commit b3051d0
Show file tree
Hide file tree
Showing 27 changed files with 458 additions and 235 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
with the year, and rearrange a comparison to avoid a potentional signed
arithmetic overflow that would give the wrong result.
ok djm@
- [email protected] 2014/01/09 23:20:00
[digest.c digest.h hostfile.c kex.c kex.h kexc25519.c kexc25519c.c]
[kexc25519s.c kexdh.c kexecdh.c kexecdhc.c kexecdhs.c kexgex.c kexgexc.c]
[kexgexs.c key.c key.h roaming_client.c roaming_common.c schnorr.c]
[schnorr.h ssh-dss.c ssh-ecdsa.c ssh-rsa.c sshconnect2.c]
Introduce digest API and use it to perform all hashing operations
rather than calling OpenSSL EVP_Digest* directly. Will make it easier
to build a reduced-feature OpenSSH without OpenSSL in future;
feedback, ok markus@

20140108
- (djm) [regress/.cvsignore] Ignore regress test droppings; ok dtucker@
Expand Down
4 changes: 2 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# $Id: Makefile.in,v 1.348 2013/12/08 04:53:28 djm Exp $
# $Id: Makefile.in,v 1.349 2014/01/09 23:58:53 djm Exp $

# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
Expand Down Expand Up @@ -75,7 +75,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \
msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \
kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \
ssh-ed25519.o \
ssh-ed25519.o digest.o \
sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o \

SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
Expand Down
148 changes: 148 additions & 0 deletions digest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/* $OpenBSD: digest.c,v 1.1 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "includes.h"

#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/bn.h> /* for buffer.h */
#include <openssl/ec.h> /* for buffer.h */
#include <openssl/evp.h>

#include "buffer.h"
#include "digest.h"

struct ssh_digest_ctx {
int alg;
EVP_MD_CTX mdctx;
};

struct ssh_digest {
int id;
const char *name;
size_t digest_len;
const EVP_MD *(*mdfunc)(void);
};

/* NB. Indexed directly by algorithm number */
const struct ssh_digest digests[] = {
{ SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
{ SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 },
{ SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
#ifdef HAVE_EVP_SHA256 /* XXX replace with local if missing */
{ SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
{ SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },
{ SSH_DIGEST_SHA512, "SHA512", 64, EVP_sha512 },
#endif
{ -1, NULL, 0, NULL },
};

static const struct ssh_digest *
ssh_digest_by_alg(int alg)
{
if (alg < 0 || alg >= SSH_DIGEST_MAX)
return NULL;
if (digests[alg].id != alg) /* sanity */
return NULL;
return &(digests[alg]);
}

size_t
ssh_digest_bytes(int alg)
{
const struct ssh_digest *digest = ssh_digest_by_alg(alg);

return digest == NULL ? 0 : digest->digest_len;
}

struct ssh_digest_ctx *
ssh_digest_start(int alg)
{
const struct ssh_digest *digest = ssh_digest_by_alg(alg);
struct ssh_digest_ctx *ret;

if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
return NULL;
ret->alg = alg;
EVP_MD_CTX_init(&ret->mdctx);
if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
free(ret);
return NULL;
}
return ret;
}

int
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
{
if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
return -1;
return 0;
}

int
ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b)
{
return ssh_digest_update(ctx, buffer_ptr(b), buffer_len(b));
}

int
ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
{
const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg);
u_int l = dlen;

if (dlen > UINT_MAX)
return -1;
if (dlen < digest->digest_len) /* No truncation allowed */
return -1;
if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
return -1;
if (l != digest->digest_len) /* sanity */
return -1;
return 0;
}

void
ssh_digest_free(struct ssh_digest_ctx *ctx)
{
EVP_MD_CTX_cleanup(&ctx->mdctx);
memset(ctx, 0, sizeof(*ctx));
}

int
ssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen)
{
struct ssh_digest_ctx *ctx = ssh_digest_start(alg);

if (ctx == NULL)
return -1;
if (ssh_digest_update(ctx, m, mlen) != 0 ||
ssh_digest_final(ctx, d, dlen) != 0)
return -1;
ssh_digest_free(ctx);
return 0;
}

int
ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
{
return ssh_digest_memory(alg, buffer_ptr(b), buffer_len(b), d, dlen);
}
55 changes: 55 additions & 0 deletions digest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef _DIGEST_H
#define _DIGEST_H

/* Maximum digest output length */
#define SSH_DIGEST_MAX_LENGTH 64

/* Digest algorithms */
#define SSH_DIGEST_MD5 0
#define SSH_DIGEST_RIPEMD160 1
#define SSH_DIGEST_SHA1 2
#define SSH_DIGEST_SHA256 3
#define SSH_DIGEST_SHA384 4
#define SSH_DIGEST_SHA512 5
#define SSH_DIGEST_MAX 6

/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
size_t ssh_digest_bytes(int alg);

/* One-shot API */
int ssh_digest_memory(int alg, const void *m, size_t mlen,
u_char *d, size_t dlen)
__attribute__((__bounded__(__buffer__, 2, 3)))
__attribute__((__bounded__(__buffer__, 4, 5)));
int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen)
__attribute__((__bounded__(__buffer__, 3, 4)));

/* Update API */
struct ssh_digest_ctx;
struct ssh_digest_ctx *ssh_digest_start(int alg);
int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
__attribute__((__bounded__(__buffer__, 2, 3)));
int ssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const Buffer *b);
int ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
__attribute__((__bounded__(__buffer__, 2, 3)));
void ssh_digest_free(struct ssh_digest_ctx *ctx);

#endif /* _DIGEST_H */

3 changes: 2 additions & 1 deletion hostfile.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.52 2013/07/12 00:19:58 djm Exp $ */
/* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */
/*
* Author: Tatu Ylonen <[email protected]>
* Copyright (c) 1995 Tatu Ylonen <[email protected]>, Espoo, Finland
Expand Down Expand Up @@ -57,6 +57,7 @@
#include "hostfile.h"
#include "log.h"
#include "misc.h"
#include "digest.h"

struct hostkeys {
struct hostkey_entry *entries;
Expand Down
Loading

0 comments on commit b3051d0

Please sign in to comment.