blob: 95bf1102cf4d7b6b6509754f8cbff6085f0524d0 [file] [log] [blame]
/* Copyright (C) 2010 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by the GPL v2 license that can
* be found in the LICENSE file.
*
* These files provide equivalent implementations for kernel calls for
* compatibility with files under SRC/include.
*/
#include <linux/bug.h>
#include <linux/scatterlist.h>
#include <linux/crypto.h>
#include <openssl/evp.h>
/* Simple static global for counting crypto references. This let's us clean up
* global OpenSSL state when the last one is freed. */
static unsigned int crypto_refs = 0;
struct hash_tfm *crypto_alloc_hash(const char *alg_name, int a, int b)
{
struct hash_tfm *tfm =
(struct hash_tfm *) calloc(sizeof(struct hash_tfm), 1);
if (!crypto_refs++)
OpenSSL_add_all_digests();
tfm->impl = EVP_get_digestbyname(alg_name);
EVP_MD_CTX_init(&tfm->ctx);
return tfm;
}
void crypto_free_hash(struct hash_tfm *tfm)
{
if (tfm) {
free(tfm);
if (--crypto_refs == 0)
EVP_cleanup();
}
}
unsigned int crypto_hash_digestsize(struct hash_tfm *tfm)
{
unsigned int len;
BUG_ON(!tfm);
/* Must be initialized before we can get a size */
len = EVP_MD_size(tfm->impl);
return len;
}
int crypto_hash_init(struct hash_desc *h)
{
EVP_MD_CTX_init(&h->tfm->ctx);
EVP_DigestInit_ex(&h->tfm->ctx, h->tfm->impl, NULL);
return 0;
}
int crypto_hash_digest(struct hash_desc *h, struct scatterlist *sg,
unsigned int sz, u8 *dst)
{
unsigned int available = 0;
char *buffer = (char *)(sg->buffer) + sg->offset;
EVP_DigestUpdate(&h->tfm->ctx, buffer, sg->length - sg->offset);
EVP_DigestFinal_ex(&h->tfm->ctx, dst, &available);
EVP_MD_CTX_cleanup(&h->tfm->ctx);
BUG_ON(available > sz);
return 0;
}
int crypto_hash_update(struct hash_desc *h, struct scatterlist *sg,
unsigned int size)
{
char *buffer = (char *)(sg->buffer) + sg->offset;
EVP_DigestUpdate(&h->tfm->ctx, buffer, sg->length - sg->offset);
return 0;
}
int crypto_hash_final(struct hash_desc *h, u8 *dst) {
unsigned int available = 0;
EVP_DigestFinal_ex(&h->tfm->ctx, dst, &available);
EVP_MD_CTX_cleanup(&h->tfm->ctx);
return 0;
}