1ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman/* $OpenBSD: digest-libc.c,v 1.5 2015/05/05 02:48:17 jsg Exp $ */ 2d059297112922cabb0c674840589be8db821fd9aAdam Langley/* 3d059297112922cabb0c674840589be8db821fd9aAdam Langley * Copyright (c) 2013 Damien Miller <djm@mindrot.org> 4d059297112922cabb0c674840589be8db821fd9aAdam Langley * Copyright (c) 2014 Markus Friedl. All rights reserved. 5d059297112922cabb0c674840589be8db821fd9aAdam Langley * 6d059297112922cabb0c674840589be8db821fd9aAdam Langley * Permission to use, copy, modify, and distribute this software for any 7d059297112922cabb0c674840589be8db821fd9aAdam Langley * purpose with or without fee is hereby granted, provided that the above 8d059297112922cabb0c674840589be8db821fd9aAdam Langley * copyright notice and this permission notice appear in all copies. 9d059297112922cabb0c674840589be8db821fd9aAdam Langley * 10d059297112922cabb0c674840589be8db821fd9aAdam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11d059297112922cabb0c674840589be8db821fd9aAdam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12d059297112922cabb0c674840589be8db821fd9aAdam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13d059297112922cabb0c674840589be8db821fd9aAdam Langley * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14d059297112922cabb0c674840589be8db821fd9aAdam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15d059297112922cabb0c674840589be8db821fd9aAdam Langley * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16d059297112922cabb0c674840589be8db821fd9aAdam Langley * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17d059297112922cabb0c674840589be8db821fd9aAdam Langley */ 18d059297112922cabb0c674840589be8db821fd9aAdam Langley 19d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "includes.h" 20d059297112922cabb0c674840589be8db821fd9aAdam Langley 21d059297112922cabb0c674840589be8db821fd9aAdam Langley#ifndef WITH_OPENSSL 22d059297112922cabb0c674840589be8db821fd9aAdam Langley 23d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <sys/types.h> 24d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <limits.h> 25d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <stdlib.h> 26d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <string.h> 27d059297112922cabb0c674840589be8db821fd9aAdam Langley 28d059297112922cabb0c674840589be8db821fd9aAdam Langley#if 0 29d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <md5.h> 30d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <rmd160.h> 31d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <sha1.h> 32d059297112922cabb0c674840589be8db821fd9aAdam Langley#include <sha2.h> 33d059297112922cabb0c674840589be8db821fd9aAdam Langley#endif 34d059297112922cabb0c674840589be8db821fd9aAdam Langley 35d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "ssherr.h" 36d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "sshbuf.h" 37d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "digest.h" 38d059297112922cabb0c674840589be8db821fd9aAdam Langley 39d059297112922cabb0c674840589be8db821fd9aAdam Langleytypedef void md_init_fn(void *mdctx); 40d059297112922cabb0c674840589be8db821fd9aAdam Langleytypedef void md_update_fn(void *mdctx, const u_int8_t *m, size_t mlen); 41d059297112922cabb0c674840589be8db821fd9aAdam Langleytypedef void md_final_fn(u_int8_t[], void *mdctx); 42d059297112922cabb0c674840589be8db821fd9aAdam Langley 43d059297112922cabb0c674840589be8db821fd9aAdam Langleystruct ssh_digest_ctx { 44d059297112922cabb0c674840589be8db821fd9aAdam Langley int alg; 45d059297112922cabb0c674840589be8db821fd9aAdam Langley void *mdctx; 46d059297112922cabb0c674840589be8db821fd9aAdam Langley}; 47d059297112922cabb0c674840589be8db821fd9aAdam Langley 48d059297112922cabb0c674840589be8db821fd9aAdam Langleystruct ssh_digest { 49d059297112922cabb0c674840589be8db821fd9aAdam Langley int id; 50d059297112922cabb0c674840589be8db821fd9aAdam Langley const char *name; 51d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t block_len; 52d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t digest_len; 53d059297112922cabb0c674840589be8db821fd9aAdam Langley size_t ctx_len; 54d059297112922cabb0c674840589be8db821fd9aAdam Langley md_init_fn *md_init; 55d059297112922cabb0c674840589be8db821fd9aAdam Langley md_update_fn *md_update; 56d059297112922cabb0c674840589be8db821fd9aAdam Langley md_final_fn *md_final; 57d059297112922cabb0c674840589be8db821fd9aAdam Langley}; 58d059297112922cabb0c674840589be8db821fd9aAdam Langley 59d059297112922cabb0c674840589be8db821fd9aAdam Langley/* NB. Indexed directly by algorithm number */ 60d059297112922cabb0c674840589be8db821fd9aAdam Langleyconst struct ssh_digest digests[SSH_DIGEST_MAX] = { 61d059297112922cabb0c674840589be8db821fd9aAdam Langley { 62d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_DIGEST_MD5, 63d059297112922cabb0c674840589be8db821fd9aAdam Langley "MD5", 64d059297112922cabb0c674840589be8db821fd9aAdam Langley MD5_BLOCK_LENGTH, 65d059297112922cabb0c674840589be8db821fd9aAdam Langley MD5_DIGEST_LENGTH, 66d059297112922cabb0c674840589be8db821fd9aAdam Langley sizeof(MD5_CTX), 67d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_init_fn *) MD5Init, 68d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_update_fn *) MD5Update, 69d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_final_fn *) MD5Final 70d059297112922cabb0c674840589be8db821fd9aAdam Langley }, 71d059297112922cabb0c674840589be8db821fd9aAdam Langley { 72d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_DIGEST_RIPEMD160, 73d059297112922cabb0c674840589be8db821fd9aAdam Langley "RIPEMD160", 74d059297112922cabb0c674840589be8db821fd9aAdam Langley RMD160_BLOCK_LENGTH, 75d059297112922cabb0c674840589be8db821fd9aAdam Langley RMD160_DIGEST_LENGTH, 76d059297112922cabb0c674840589be8db821fd9aAdam Langley sizeof(RMD160_CTX), 77d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_init_fn *) RMD160Init, 78d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_update_fn *) RMD160Update, 79d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_final_fn *) RMD160Final 80d059297112922cabb0c674840589be8db821fd9aAdam Langley }, 81d059297112922cabb0c674840589be8db821fd9aAdam Langley { 82d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_DIGEST_SHA1, 83d059297112922cabb0c674840589be8db821fd9aAdam Langley "SHA1", 84d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA1_BLOCK_LENGTH, 85d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA1_DIGEST_LENGTH, 86d059297112922cabb0c674840589be8db821fd9aAdam Langley sizeof(SHA1_CTX), 87d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_init_fn *) SHA1Init, 88d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_update_fn *) SHA1Update, 89d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_final_fn *) SHA1Final 90d059297112922cabb0c674840589be8db821fd9aAdam Langley }, 91d059297112922cabb0c674840589be8db821fd9aAdam Langley { 92d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_DIGEST_SHA256, 93d059297112922cabb0c674840589be8db821fd9aAdam Langley "SHA256", 94d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA256_BLOCK_LENGTH, 95d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA256_DIGEST_LENGTH, 96d059297112922cabb0c674840589be8db821fd9aAdam Langley sizeof(SHA256_CTX), 97d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_init_fn *) SHA256_Init, 98d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_update_fn *) SHA256_Update, 99d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_final_fn *) SHA256_Final 100d059297112922cabb0c674840589be8db821fd9aAdam Langley }, 101d059297112922cabb0c674840589be8db821fd9aAdam Langley { 102d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_DIGEST_SHA384, 103d059297112922cabb0c674840589be8db821fd9aAdam Langley "SHA384", 104d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA384_BLOCK_LENGTH, 105d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA384_DIGEST_LENGTH, 106d059297112922cabb0c674840589be8db821fd9aAdam Langley sizeof(SHA384_CTX), 107d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_init_fn *) SHA384_Init, 108d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_update_fn *) SHA384_Update, 109d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_final_fn *) SHA384_Final 110d059297112922cabb0c674840589be8db821fd9aAdam Langley }, 111d059297112922cabb0c674840589be8db821fd9aAdam Langley { 112d059297112922cabb0c674840589be8db821fd9aAdam Langley SSH_DIGEST_SHA512, 113d059297112922cabb0c674840589be8db821fd9aAdam Langley "SHA512", 114d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA512_BLOCK_LENGTH, 115d059297112922cabb0c674840589be8db821fd9aAdam Langley SHA512_DIGEST_LENGTH, 116d059297112922cabb0c674840589be8db821fd9aAdam Langley sizeof(SHA512_CTX), 117d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_init_fn *) SHA512_Init, 118d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_update_fn *) SHA512_Update, 119d059297112922cabb0c674840589be8db821fd9aAdam Langley (md_final_fn *) SHA512_Final 120d059297112922cabb0c674840589be8db821fd9aAdam Langley } 121d059297112922cabb0c674840589be8db821fd9aAdam Langley}; 122d059297112922cabb0c674840589be8db821fd9aAdam Langley 123d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic const struct ssh_digest * 124d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_by_alg(int alg) 125d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 126d059297112922cabb0c674840589be8db821fd9aAdam Langley if (alg < 0 || alg >= SSH_DIGEST_MAX) 127d059297112922cabb0c674840589be8db821fd9aAdam Langley return NULL; 128d059297112922cabb0c674840589be8db821fd9aAdam Langley if (digests[alg].id != alg) /* sanity */ 129d059297112922cabb0c674840589be8db821fd9aAdam Langley return NULL; 130d059297112922cabb0c674840589be8db821fd9aAdam Langley return &(digests[alg]); 131d059297112922cabb0c674840589be8db821fd9aAdam Langley} 132d059297112922cabb0c674840589be8db821fd9aAdam Langley 133d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 134d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_alg_by_name(const char *name) 135d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 136d059297112922cabb0c674840589be8db821fd9aAdam Langley int alg; 137d059297112922cabb0c674840589be8db821fd9aAdam Langley 138d059297112922cabb0c674840589be8db821fd9aAdam Langley for (alg = 0; alg < SSH_DIGEST_MAX; alg++) { 139d059297112922cabb0c674840589be8db821fd9aAdam Langley if (strcasecmp(name, digests[alg].name) == 0) 140d059297112922cabb0c674840589be8db821fd9aAdam Langley return digests[alg].id; 141d059297112922cabb0c674840589be8db821fd9aAdam Langley } 142d059297112922cabb0c674840589be8db821fd9aAdam Langley return -1; 143d059297112922cabb0c674840589be8db821fd9aAdam Langley} 144d059297112922cabb0c674840589be8db821fd9aAdam Langley 145d059297112922cabb0c674840589be8db821fd9aAdam Langleyconst char * 146d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_alg_name(int alg) 147d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 148d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(alg); 149d059297112922cabb0c674840589be8db821fd9aAdam Langley 150d059297112922cabb0c674840589be8db821fd9aAdam Langley return digest == NULL ? NULL : digest->name; 151d059297112922cabb0c674840589be8db821fd9aAdam Langley} 152d059297112922cabb0c674840589be8db821fd9aAdam Langley 153d059297112922cabb0c674840589be8db821fd9aAdam Langleysize_t 154d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_bytes(int alg) 155d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 156d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(alg); 157d059297112922cabb0c674840589be8db821fd9aAdam Langley 158d059297112922cabb0c674840589be8db821fd9aAdam Langley return digest == NULL ? 0 : digest->digest_len; 159d059297112922cabb0c674840589be8db821fd9aAdam Langley} 160d059297112922cabb0c674840589be8db821fd9aAdam Langley 161d059297112922cabb0c674840589be8db821fd9aAdam Langleysize_t 162d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_blocksize(struct ssh_digest_ctx *ctx) 163d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 164d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); 165d059297112922cabb0c674840589be8db821fd9aAdam Langley 166d059297112922cabb0c674840589be8db821fd9aAdam Langley return digest == NULL ? 0 : digest->block_len; 167d059297112922cabb0c674840589be8db821fd9aAdam Langley} 168d059297112922cabb0c674840589be8db821fd9aAdam Langley 169d059297112922cabb0c674840589be8db821fd9aAdam Langleystruct ssh_digest_ctx * 170d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_start(int alg) 171d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 172d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(alg); 173d059297112922cabb0c674840589be8db821fd9aAdam Langley struct ssh_digest_ctx *ret; 174d059297112922cabb0c674840589be8db821fd9aAdam Langley 175ccacbc9b0331c30b8be12e8e0349e983abf28fc0Greg Hartman if (digest == NULL || (ret = calloc(1, sizeof(*ret))) == NULL) 176d059297112922cabb0c674840589be8db821fd9aAdam Langley return NULL; 177d059297112922cabb0c674840589be8db821fd9aAdam Langley if ((ret->mdctx = calloc(1, digest->ctx_len)) == NULL) { 178d059297112922cabb0c674840589be8db821fd9aAdam Langley free(ret); 179d059297112922cabb0c674840589be8db821fd9aAdam Langley return NULL; 180d059297112922cabb0c674840589be8db821fd9aAdam Langley } 181d059297112922cabb0c674840589be8db821fd9aAdam Langley ret->alg = alg; 182d059297112922cabb0c674840589be8db821fd9aAdam Langley digest->md_init(ret->mdctx); 183d059297112922cabb0c674840589be8db821fd9aAdam Langley return ret; 184d059297112922cabb0c674840589be8db821fd9aAdam Langley} 185d059297112922cabb0c674840589be8db821fd9aAdam Langley 186d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 187d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) 188d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 189d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(from->alg); 190d059297112922cabb0c674840589be8db821fd9aAdam Langley 191d059297112922cabb0c674840589be8db821fd9aAdam Langley if (digest == NULL || from->alg != to->alg) 192d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 193d059297112922cabb0c674840589be8db821fd9aAdam Langley memcpy(to->mdctx, from->mdctx, digest->ctx_len); 194d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 195d059297112922cabb0c674840589be8db821fd9aAdam Langley} 196d059297112922cabb0c674840589be8db821fd9aAdam Langley 197d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 198d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 199d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 200d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); 201d059297112922cabb0c674840589be8db821fd9aAdam Langley 202d059297112922cabb0c674840589be8db821fd9aAdam Langley if (digest == NULL) 203d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 204d059297112922cabb0c674840589be8db821fd9aAdam Langley digest->md_update(ctx->mdctx, m, mlen); 205d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 206d059297112922cabb0c674840589be8db821fd9aAdam Langley} 207d059297112922cabb0c674840589be8db821fd9aAdam Langley 208d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 209d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_update_buffer(struct ssh_digest_ctx *ctx, const struct sshbuf *b) 210d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 211d059297112922cabb0c674840589be8db821fd9aAdam Langley return ssh_digest_update(ctx, sshbuf_ptr(b), sshbuf_len(b)); 212d059297112922cabb0c674840589be8db821fd9aAdam Langley} 213d059297112922cabb0c674840589be8db821fd9aAdam Langley 214d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 215d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) 216d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 217d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest = ssh_digest_by_alg(ctx->alg); 218d059297112922cabb0c674840589be8db821fd9aAdam Langley 219d059297112922cabb0c674840589be8db821fd9aAdam Langley if (digest == NULL) 220d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 221d059297112922cabb0c674840589be8db821fd9aAdam Langley if (dlen > UINT_MAX) 222d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 223d059297112922cabb0c674840589be8db821fd9aAdam Langley if (dlen < digest->digest_len) /* No truncation allowed */ 224d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 225d059297112922cabb0c674840589be8db821fd9aAdam Langley digest->md_final(d, ctx->mdctx); 226d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 227d059297112922cabb0c674840589be8db821fd9aAdam Langley} 228d059297112922cabb0c674840589be8db821fd9aAdam Langley 229d059297112922cabb0c674840589be8db821fd9aAdam Langleyvoid 230d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_free(struct ssh_digest_ctx *ctx) 231d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 232d059297112922cabb0c674840589be8db821fd9aAdam Langley const struct ssh_digest *digest; 233d059297112922cabb0c674840589be8db821fd9aAdam Langley 234d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ctx != NULL) { 235d059297112922cabb0c674840589be8db821fd9aAdam Langley digest = ssh_digest_by_alg(ctx->alg); 236d059297112922cabb0c674840589be8db821fd9aAdam Langley if (digest) { 237d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(ctx->mdctx, digest->ctx_len); 238d059297112922cabb0c674840589be8db821fd9aAdam Langley free(ctx->mdctx); 239d059297112922cabb0c674840589be8db821fd9aAdam Langley explicit_bzero(ctx, sizeof(*ctx)); 240d059297112922cabb0c674840589be8db821fd9aAdam Langley free(ctx); 241d059297112922cabb0c674840589be8db821fd9aAdam Langley } 242d059297112922cabb0c674840589be8db821fd9aAdam Langley } 243d059297112922cabb0c674840589be8db821fd9aAdam Langley} 244d059297112922cabb0c674840589be8db821fd9aAdam Langley 245d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 246d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_memory(int alg, const void *m, size_t mlen, u_char *d, size_t dlen) 247d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 248d059297112922cabb0c674840589be8db821fd9aAdam Langley struct ssh_digest_ctx *ctx = ssh_digest_start(alg); 249d059297112922cabb0c674840589be8db821fd9aAdam Langley 250d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ctx == NULL) 251d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 252d059297112922cabb0c674840589be8db821fd9aAdam Langley if (ssh_digest_update(ctx, m, mlen) != 0 || 253d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_digest_final(ctx, d, dlen) != 0) 254d059297112922cabb0c674840589be8db821fd9aAdam Langley return SSH_ERR_INVALID_ARGUMENT; 255d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_digest_free(ctx); 256d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 257d059297112922cabb0c674840589be8db821fd9aAdam Langley} 258d059297112922cabb0c674840589be8db821fd9aAdam Langley 259d059297112922cabb0c674840589be8db821fd9aAdam Langleyint 260d059297112922cabb0c674840589be8db821fd9aAdam Langleyssh_digest_buffer(int alg, const struct sshbuf *b, u_char *d, size_t dlen) 261d059297112922cabb0c674840589be8db821fd9aAdam Langley{ 262d059297112922cabb0c674840589be8db821fd9aAdam Langley return ssh_digest_memory(alg, sshbuf_ptr(b), sshbuf_len(b), d, dlen); 263d059297112922cabb0c674840589be8db821fd9aAdam Langley} 264d059297112922cabb0c674840589be8db821fd9aAdam Langley#endif /* !WITH_OPENSSL */ 265