OpenSSL对称加密算法中如何添加新算法

1.关于加密算法的加载
在调用加密算法之前,通过调用OpenSSL_add_all_algorithms来加载加密算法函数和单向散列算法函数
void OpenSSL_add_all_algorithms(void)
{
OpenSSL_add_all_ciphers(); /* 加载加密算法 */
OpenSSL_add_all_digests(); /* 加载单向散列函数 */
}
void OpenSSL_add_all_ciphers(void)函数实现如下:
void OpenSSL_add_all_ciphers(void)
{
EVP_add_cipher(EVP_rc2_cfb());
。。。。。。
PKCS12_PBE_add();
PKCS5_PBE_add();
}
/* 这个过程的主要任务是向全局变量,static LHASH *names_lh,注册加密算法,如果添加了新的加密算法,必需向names_lh注册。 */
由于DES算法接口内容较多,所以我们从IDEA算法的接口开始研究!
#ifndef NO_IDEA
EVP_add_cipher(EVP_idea_ecb()); /*添加EBC加密模式 */
EVP_add_cipher(EVP_idea_cfb()); /*添加CFB加密模式 */
EVP_add_cipher(EVP_idea_ofb()); /*添加OCF加密模式 */
EVP_add_cipher(EVP_idea_cbc()); /*添加CBC加密模式 */
EVP_add_cipher_alias(SN_idea_cbc,"IDEA"); /*添加cbc加密算法的别名 “IDEA” */
EVP_add_cipher_alias(SN_idea_cbc,"idea"); /*添加cbc加密算法的别名 “idea” */
#endif
在包括IDEA加密算法的情况下,OpenSSL将会选择IDAE加密算法模块!
下面来看看EVP_add_cipher函数是怎么实现的,
int EVP_add_cipher(EVP_CIPHER *c)
{
int r;
r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(char *)c);
if (r == 0) return(0);
r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(char *)c);
return(r);
}
/* 向全决变量names_lh 注册 obj_name_types 变量的过程 */
int OBJ_NAME_add(const char *name, int type, const char *data)
{
OBJ_NAME *onp,*ret;
int alias;
if ((names_lh == NULL) && !OBJ_NAME_init()) return(0);
alias=type&OBJ_NAME_ALIAS;
type&= ~OBJ_NAME_ALIAS;
onp=(OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
if (onp == NULL)
{
/* ERROR */
return(0);
}
onp->name=name;
onp->alias=alias;
onp->type=type;
onp->data=data;
ret=(OBJ_NAME *)lh_insert(names_lh,onp);
if (ret != NULL)
{
/* free things */
if ((name_funcs_stack != NULL) && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type))
{
/* XXX: I'm not sure I understand why the free
* function should get three arguments...
* -- Richard Levitte
*/
sk_NAME_FUNCS_value(name_funcs_stack,ret->type)
->free_func(ret->name,ret->type,ret->data);
}
OPENSSL_free(ret);
}
else
{
if (lh_error(names_lh))
{
/* ERROR */
return(0);
}
}
return(1);
}
names_lh 是 LHASH的全局变量,用于维护obj_name_types的类型的变量。(在crypt/objects/o_names.c中定义)
(crypt/objects/obj_dat.h)相关的全局变量
static unsigned char lvalues[2896] 全局变量,已经初始化,存放了OpenSSL所有Object的相关信息。
nid_objs 是ASN1_OBJECT结构的数组全局变量,已经初始化,记录了所有OpenSSL用到的类型的名字
static ASN1_OBJECT *sn_objs[NUM_SN] 全局变量,已经初始化。
static ASN1_OBJECT *ln_objs[NUM_LN] 全局变量,已经初始化。
crypt/object/objects.h 中定义的结构
typedef struct obj_name_st
{
int type;
int alias;
const char *name;
const char *data;
} OBJ_NAME;
注意:crypto/objects 目录下面维护整个OpenSSL模块化的重要的程序,下面逐个做出介绍。
objects.txt 按照一定的语法结构,定义了SN_base, LN_base, NID_base,OBJ_base。经过perl程序objects.pl通过命令perl objects.pl objects.txt obj_mac.num obj_mac.h 处理后,生成了obj_mac.num 和obj_mac.h两个文件。
obj_mac.num 用来查阅 OBJ_base与NID_base之间的对应关系。
obj_mac.h 用来提供c语言类型SN_base, LN_base, NID_base,OBJ_base定义。
objects.h 同样提供了c语言类型SN_base, LN_base, NID_base,OBJ_base定义,在obj_mac.h 更新之后,必须对对应的objects.h 中的内容作出同步,及保持与obj_mac.h的定义一至,同时objects.h中也声明了一些对OBJ_name的操作函数。
objects.h 经过perl程序perl obj_dat.pl objects.h obj_dat.h处理之后,生成obj_dat.h头文件。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzwfsg.html