version 1.7, 2017/05/08 22:57:38 |
version 1.8, 2018/09/13 02:08:33 |
|
|
|
|
struct ssh_digest_ctx { |
struct ssh_digest_ctx { |
int alg; |
int alg; |
EVP_MD_CTX mdctx; |
EVP_MD_CTX *mdctx; |
}; |
}; |
|
|
struct ssh_digest { |
struct ssh_digest { |
|
|
size_t |
size_t |
ssh_digest_blocksize(struct ssh_digest_ctx *ctx) |
ssh_digest_blocksize(struct ssh_digest_ctx *ctx) |
{ |
{ |
return EVP_MD_CTX_block_size(&ctx->mdctx); |
return EVP_MD_CTX_block_size(ctx->mdctx); |
} |
} |
|
|
struct ssh_digest_ctx * |
struct ssh_digest_ctx * |
|
|
if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) |
if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) |
return NULL; |
return NULL; |
ret->alg = alg; |
ret->alg = alg; |
EVP_MD_CTX_init(&ret->mdctx); |
if ((ret->mdctx = EVP_MD_CTX_new()) == NULL) { |
if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { |
|
free(ret); |
free(ret); |
return NULL; |
return NULL; |
} |
} |
|
if (EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) { |
|
ssh_digest_free(ret); |
|
return NULL; |
|
} |
return ret; |
return ret; |
} |
} |
|
|
|
|
if (from->alg != to->alg) |
if (from->alg != to->alg) |
return SSH_ERR_INVALID_ARGUMENT; |
return SSH_ERR_INVALID_ARGUMENT; |
/* we have bcopy-style order while openssl has memcpy-style */ |
/* we have bcopy-style order while openssl has memcpy-style */ |
if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) |
if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx)) |
return SSH_ERR_LIBCRYPTO_ERROR; |
return SSH_ERR_LIBCRYPTO_ERROR; |
return 0; |
return 0; |
} |
} |
|
|
int |
int |
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) |
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) |
{ |
{ |
if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) |
if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1) |
return SSH_ERR_LIBCRYPTO_ERROR; |
return SSH_ERR_LIBCRYPTO_ERROR; |
return 0; |
return 0; |
} |
} |
|
|
return SSH_ERR_INVALID_ARGUMENT; |
return SSH_ERR_INVALID_ARGUMENT; |
if (dlen < digest->digest_len) /* No truncation allowed */ |
if (dlen < digest->digest_len) /* No truncation allowed */ |
return SSH_ERR_INVALID_ARGUMENT; |
return SSH_ERR_INVALID_ARGUMENT; |
if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1) |
if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1) |
return SSH_ERR_LIBCRYPTO_ERROR; |
return SSH_ERR_LIBCRYPTO_ERROR; |
if (l != digest->digest_len) /* sanity */ |
if (l != digest->digest_len) /* sanity */ |
return SSH_ERR_INTERNAL_ERROR; |
return SSH_ERR_INTERNAL_ERROR; |
|
|
void |
void |
ssh_digest_free(struct ssh_digest_ctx *ctx) |
ssh_digest_free(struct ssh_digest_ctx *ctx) |
{ |
{ |
if (ctx != NULL) { |
if (ctx == NULL) |
EVP_MD_CTX_cleanup(&ctx->mdctx); |
return; |
explicit_bzero(ctx, sizeof(*ctx)); |
EVP_MD_CTX_free(ctx->mdctx); |
free(ctx); |
freezero(ctx, sizeof(*ctx)); |
} |
|
} |
} |
|
|
int |
int |