1. 前言
OpenSSL是一个开源的SSL实现,其中集成了多种加密算法。OpenSSL将各算法的各自独特地方封装在内部,对外则使用了统一的算法接口,因此外部应用只需指定使用何种算法,就可以用相同的方法调用加解密函数而不用考虑其差异。这种算法统一封装的方式在其他很多软件中都采用,也给算法扩充提供了方便。
以下代码来自OpenSSL-0.9.7b。
2. EVP接口
2.1 数据结构
Openssl/crypto/evp目录下定义各种算法的接口源文件,这些文件要作的事就是要填写描述算法的EVP_CIPHER结构,每个算法都有一个EVP_CIPHER结构进行描述:
Openssl/crypto/evp/evp.h
struct evp_cipher_st
{
int nid;
int block_size;
int key_len; /* Default value for variable length ciphers */
int iv_len;
unsigned long flags; /* Various flags */
int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc); /* init key */
int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
int ctx_size; /* how big ctx->cipher_data needs to be */
int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
void *app_data; /* Application data */
} /* EVP_CIPHER */;
typedef struct evp_cipher_st EVP_CIPHER;
nid:算法的ID号,在include/openssl/object.h中定义;
block_size:加解密的分组长度
key_len:密钥长度
iv_len:初始向量长度
flags:标志
(* init):初始化函数,提供密钥,IV向量,算法上下文CTX,加密还是解密
(* do_cipher):加解密函数,提供算法上下文CTX,输出数据,输入数据和输入数据长度
(* clean_up):资源释放
ctx_size:各算法相关数据大小,实际就是各算法的密钥数据
(*set_asn1_parameters):设置asn1参数
(*get_asn1_parameters):获取asn1参数
(*ctrl):其他控制操作
app_data:算法相关数据
另一个重要的数据结构是描述加密算法的上下文结构EVP_CIPHER_CTX,这个结构是进入算法前由系统根据指定的算法提供的:
struct evp_cipher_ctx_st
{
const EVP_CIPHER *cipher;
ENGINE *engine; /* functional reference if 'cipher' is ENGINE-provided */
int encrypt; /* encrypt or decrypt */
int buf_len; /* number we have left */
unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
int num; /* used by cfb/ofb mode */
void *app_data; /* application stuff */
int key_len; /* May change for variable length cipher */
unsigned long flags; /* Various flags */
void *cipher_data; /* per EVP data */
int final_used;
int block_mask;
unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
} /* EVP_CIPHER_CTX */;
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
参数为:
cipher:算法指针
engine:加解密引擎
encrypt:加密或解密
buf_len:剩余空间
oiv:原始的初始向量