📄 evp.c
字号:
/* * Copyright (c) 2006 - 2007 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifdef HAVE_CONFIG_H#include <config.h>#endifRCSID("$Id: evp.c 22379 2007-12-29 11:13:26Z lha $");#include <sys/types.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include <evp.h>#include <krb5-types.h>#include <aes.h>#include "camellia.h"#include <des.h>#include <sha.h>#include <rc2.h>#include <rc4.h>#include <md2.h>#include <md4.h>#include <md5.h>/** * @page page_evp EVP - generic crypto interface * * See the library functions here: @ref hcrypto_evp */typedef int (*evp_md_init)(EVP_MD_CTX *);typedef int (*evp_md_update)(EVP_MD_CTX *,const void *, size_t);typedef int (*evp_md_final)(void *, EVP_MD_CTX *);typedef int (*evp_md_cleanup)(EVP_MD_CTX *);struct hc_evp_md { int hash_size; int block_size; int ctx_size; evp_md_init init; evp_md_update update; evp_md_final final; evp_md_cleanup cleanup;};/** * Return the output size of the message digest function. * * @param md the evp message * * @return size output size of the message digest function. * * @ingroup hcrypto_evp */size_tEVP_MD_size(const EVP_MD *md){ return md->hash_size;}/** * Return the blocksize of the message digest function. * * @param md the evp message * * @return size size of the message digest block size * * @ingroup hcrypto_evp */size_tEVP_MD_block_size(const EVP_MD *md){ return md->block_size;}/** * Allocate a messsage digest context object. Free with * EVP_MD_CTX_destroy(). * * @return a newly allocated message digest context object. * * @ingroup hcrypto_evp */EVP_MD_CTX *EVP_MD_CTX_create(void){ return calloc(1, sizeof(EVP_MD_CTX));}/** * Initiate a messsage digest context object. Deallocate with * EVP_MD_CTX_cleanup(). Please use EVP_MD_CTX_create() instead. * * @param ctx variable to initiate. * * @ingroup hcrypto_evp */voidEVP_MD_CTX_init(EVP_MD_CTX *ctx){ memset(ctx, 0, sizeof(*ctx));}/** * Free a messsage digest context object. * * @param ctx context to free. * * @ingroup hcrypto_evp */voidEVP_MD_CTX_destroy(EVP_MD_CTX *ctx){ EVP_MD_CTX_cleanup(ctx); free(ctx);}/** * Free the resources used by the EVP_MD context. * * @param ctx the context to free the resources from. * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_MD_CTX_cleanup(EVP_MD_CTX *ctx){ if (ctx->md && ctx->md->cleanup) (ctx->md->cleanup)(ctx); ctx->md = NULL; ctx->engine = NULL; free(ctx->ptr); memset(ctx, 0, sizeof(*ctx)); return 1;}/** * Get the EVP_MD use for a specified context. * * @param ctx the EVP_MD context to get the EVP_MD for. * * @return the EVP_MD used for the context. * * @ingroup hcrypto_evp */const EVP_MD *EVP_MD_CTX_md(EVP_MD_CTX *ctx){ return ctx->md;}/** * Return the output size of the message digest function. * * @param ctx the evp message digest context * * @return size output size of the message digest function. * * @ingroup hcrypto_evp */size_tEVP_MD_CTX_size(EVP_MD_CTX *ctx){ return EVP_MD_size(ctx->md);}/** * Return the blocksize of the message digest function. * * @param ctx the evp message digest context * * @return size size of the message digest block size * * @ingroup hcrypto_evp */size_tEVP_MD_CTX_block_size(EVP_MD_CTX *ctx){ return EVP_MD_block_size(ctx->md);}/** * Init a EVP_MD_CTX for use a specific message digest and engine. * * @param ctx the message digest context to init. * @param md the message digest to use. * @param engine the engine to use, NULL to use the default engine. * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *engine){ if (ctx->md != md || ctx->engine != engine) { EVP_MD_CTX_cleanup(ctx); ctx->md = md; ctx->engine = engine; ctx->ptr = calloc(1, md->ctx_size); if (ctx->ptr == NULL) return 0; } (ctx->md->init)(ctx->ptr); return 1;}/** * Update the digest with some data. * * @param ctx the context to update * @param data the data to update the context with * @param size length of data * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t size){ (ctx->md->update)(ctx->ptr, data, size); return 1;}/** * Complete the message digest. * * @param ctx the context to complete. * @param hash the output of the message digest function. At least * EVP_MD_size(). * @param size the output size of hash. * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_DigestFinal_ex(EVP_MD_CTX *ctx, void *hash, unsigned int *size){ (ctx->md->final)(hash, ctx->ptr); if (size) *size = ctx->md->hash_size; return 1;}/** * Do the whole EVP_MD_CTX_create(), EVP_DigestInit_ex(), * EVP_DigestUpdate(), EVP_DigestFinal_ex(), EVP_MD_CTX_destroy() * dance in one call. * * @param data the data to update the context with * @param dsize length of data * @param hash output data of at least EVP_MD_size() length. * @param hsize output length of hash. * @param md message digest to use * @param engine engine to use, NULL for default engine. * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_Digest(const void *data, size_t dsize, void *hash, unsigned int *hsize, const EVP_MD *md, ENGINE *engine){ EVP_MD_CTX *ctx; int ret; ctx = EVP_MD_CTX_create(); if (ctx == NULL) return 0; ret = EVP_DigestInit_ex(ctx, md, engine); if (ret != 1) { EVP_MD_CTX_destroy(ctx); return ret; } ret = EVP_DigestUpdate(ctx, data, dsize); if (ret != 1) { EVP_MD_CTX_destroy(ctx); return ret; } ret = EVP_DigestFinal_ex(ctx, hash, hsize); EVP_MD_CTX_destroy(ctx); return ret;}/** * The message digest SHA256 * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_sha256(void){ static const struct hc_evp_md sha256 = { 32, 64, sizeof(SHA256_CTX), (evp_md_init)SHA256_Init, (evp_md_update)SHA256_Update, (evp_md_final)SHA256_Final, NULL }; return &sha256;}static const struct hc_evp_md sha1 = { 20, 64, sizeof(SHA_CTX), (evp_md_init)SHA1_Init, (evp_md_update)SHA1_Update, (evp_md_final)SHA1_Final, NULL};/** * The message digest SHA1 * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_sha1(void){ return &sha1;}/** * The message digest SHA1 * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_sha(void){ return &sha1;}/** * The message digest MD5 * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_md5(void){ static const struct hc_evp_md md5 = { 16, 64, sizeof(MD5_CTX), (evp_md_init)MD5_Init, (evp_md_update)MD5_Update, (evp_md_final)MD5_Final, NULL }; return &md5;}/** * The message digest MD4 * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_md4(void){ static const struct hc_evp_md md4 = { 16, 64, sizeof(MD4_CTX), (evp_md_init)MD4_Init, (evp_md_update)MD4_Update, (evp_md_final)MD4_Final, NULL }; return &md4;}/** * The message digest MD2 * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_md2(void){ static const struct hc_evp_md md2 = { 16, 16, sizeof(MD2_CTX), (evp_md_init)MD2_Init, (evp_md_update)MD2_Update, (evp_md_final)MD2_Final, NULL }; return &md2;}/* * */static voidnull_Init (void *m){}static voidnull_Update (void *m, const void * data, size_t size){}static voidnull_Final(void *res, void *m){}/** * The null message digest * * @return the message digest type. * * @ingroup hcrypto_evp */const EVP_MD *EVP_md_null(void){ static const struct hc_evp_md null = { 0, 0, 0, (evp_md_init)null_Init, (evp_md_update)null_Update, (evp_md_final)null_Final, NULL }; return &null;}#if 0void EVP_MD_CTX_init(EVP_MD_CTX *ctx);int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);int EVP_SignFinal(EVP_MD_CTX *, void *, size_t *, EVP_PKEY *);int EVP_VerifyFinal(EVP_MD_CTX *, const void *, size_t, EVP_PKEY *);#endif/** * Return the block size of the cipher. * * @param c cipher to get the block size from. * * @return the block size of the cipher. * * @ingroup hcrypto_evp */size_tEVP_CIPHER_block_size(const EVP_CIPHER *c){ return c->block_size;}/** * Return the key size of the cipher. * * @param c cipher to get the key size from. * * @return the key size of the cipher. * * @ingroup hcrypto_evp */size_tEVP_CIPHER_key_length(const EVP_CIPHER *c){ return c->key_len;}/** * Return the IV size of the cipher. * * @param c cipher to get the IV size from. * * @return the IV size of the cipher. * * @ingroup hcrypto_evp */size_tEVP_CIPHER_iv_length(const EVP_CIPHER *c){ return c->iv_len;}/** * Initiate a EVP_CIPHER_CTX context. Clean up with * EVP_CIPHER_CTX_cleanup(). * * @param c the cipher initiate. * * @ingroup hcrypto_evp */voidEVP_CIPHER_CTX_init(EVP_CIPHER_CTX *c){ memset(c, 0, sizeof(*c));}/** * Clean up the EVP_CIPHER_CTX context. * * @param c the cipher to clean up. * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c){ if (c->cipher && c->cipher->cleanup) c->cipher->cleanup(c); if (c->cipher_data) { free(c->cipher_data); c->cipher_data = NULL; } return 1;}#if 0intEVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int length){ return 0;}intEVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad){ return 0;}#endif/** * Return the EVP_CIPHER for a EVP_CIPHER_CTX context. * * @param ctx the context to get the cipher type from. * * @return the EVP_CIPHER pointer. * * @ingroup hcrypto_evp */const EVP_CIPHER *EVP_CIPHER_CTX_cipher(EVP_CIPHER_CTX *ctx){ return ctx->cipher;}/** * Return the block size of the cipher context. * * @param ctx cipher context to get the block size from. * * @return the block size of the cipher context. * * @ingroup hcrypto_evp */size_tEVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx){ return EVP_CIPHER_block_size(ctx->cipher);}/** * Return the key size of the cipher context. * * @param ctx cipher context to get the key size from. * * @return the key size of the cipher context. * * @ingroup hcrypto_evp */size_tEVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx){ return EVP_CIPHER_key_length(ctx->cipher);}/** * Return the IV size of the cipher context. * * @param ctx cipher context to get the IV size from. * * @return the IV size of the cipher context. * * @ingroup hcrypto_evp */size_tEVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx){ return EVP_CIPHER_iv_length(ctx->cipher);}/** * Get the flags for an EVP_CIPHER_CTX context. * * @param ctx the EVP_CIPHER_CTX to get the flags from * * @return the flags for an EVP_CIPHER_CTX. * * @ingroup hcrypto_evp */unsigned longEVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx){ return ctx->cipher->flags;}/** * Get the mode for an EVP_CIPHER_CTX context. * * @param ctx the EVP_CIPHER_CTX to get the mode from * * @return the mode for an EVP_CIPHER_CTX. * * @ingroup hcrypto_evp */intEVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx){ return EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_MODE;}/** * Get the app data for an EVP_CIPHER_CTX context. * * @param ctx the EVP_CIPHER_CTX to get the app data from * * @return the app data for an EVP_CIPHER_CTX. * * @ingroup hcrypto_evp */void *EVP_CIPHER_CTX_get_app_data(EVP_CIPHER_CTX *ctx){ return ctx->app_data;}/** * Set the app data for an EVP_CIPHER_CTX context. * * @param ctx the EVP_CIPHER_CTX to set the app data for * @param data the app data to set for an EVP_CIPHER_CTX. * * @ingroup hcrypto_evp */voidEVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data){ ctx->app_data = data;}/** * Initiate the EVP_CIPHER_CTX context to encrypt or decrypt data. * Clean up with EVP_CIPHER_CTX_cleanup(). * * @param ctx context to initiate * @param c cipher to use. * @param engine crypto engine to use, NULL to select default. * @param key the crypto key to use, NULL will use the previous value. * @param iv the IV to use, NULL will use the previous value. * @param encp non zero will encrypt, -1 use the previous value. * * @return 1 on success. * * @ingroup hcrypto_evp */intEVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *c, ENGINE *engine, const void *key, const void *iv, int encp){ if (encp == -1) encp = ctx->encrypt; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -