📄 ipsec_alg_cryptoapi.c
字号:
cptr->alg.ixt_keyminbits, cptr->alg.ixt_keymaxbits, ret); return ret;}/* * bind cryptoapi cipher to ipsec_alg_capi_cipher "hyper" struct * it will also create 1 lock() inside cipher */static struct cipher_implementation *_capi_ci_bind(struct ipsec_alg_capi_cipher *cptr, struct cipher_implementation *ci){ if (atomic_read(&cptr->ci_usecnt) == 0) { cptr->ci=ci? ci : setup_cipher(cptr->ciphername); } if (cptr->ci) { atomic_inc(&cptr->ci_usecnt); cptr->ci->lock(); } return cptr->ci;}/* * unbind cryptoapi cipher from ipsec_alg_capi_cipher "hyper" struct, * will do 1 unlock() */static void_capi_ci_unbind(struct ipsec_alg_capi_cipher *cptr){ struct cipher_implementation *ci = cptr->ci; if (ci) { if (atomic_dec_and_test(&cptr->ci_usecnt) ) { cptr->ci = NULL; } ci->unlock(); }}/* * called in ipsec_sa_wipe() time, will destroy key contexts * and do 1 unbind() */static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e){ struct cipher_context *cx = (struct cipher_context *)key_e; struct cipher_implementation* ci=cx->ci; struct ipsec_alg_capi_cipher *cptr = alg->ixt_data; if (debug > 0) printk(KERN_DEBUG "klips_debug: _capi_destroy_key:" "name=%s key_e=%p ci=%p\n", alg->ixt_name, key_e, ci); if (!cx) { printk(KERN_ERR "klips_debug: _capi_destroy_key:" "name=%s NULL key_e!\n", alg->ixt_name); return; } ci->wipe_context(cx); ci->free_context(cx); /* ci->unlock(); */ _capi_ci_unbind(cptr);} /* * create new key context, need alg->ixt_data to know which * (of many) cipher inside this module is the target */static __u8 *_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen){ struct cipher_context *cx = NULL; struct ipsec_alg_capi_cipher *cptr; struct cipher_implementation *ci; cptr = alg->ixt_data; if (!cptr) { printk(KERN_ERR "_capi_new_key(): " "NULL ixt_data (?!) for \"%s\" algo\n" , alg->ixt_name); goto err; } if (debug > 0) printk(KERN_DEBUG "klips_debug:_capi_new_key:" "name=%s cptr=%p key=%p keysize=%d\n", alg->ixt_name, cptr, key, keylen); /* * sortof "cache": try to bind the cipher (will be noop if * already in use); if 1st SA using this cipher will * end doing find_cipher_by_name() * * this logic is needed to support "latebind" */ if (!(ci=_capi_ci_bind(cptr, NULL))) goto err; /* ci->lock (); */ if (debug > 0) printk(KERN_DEBUG "klips_debug:_capi_new_key (after setup):" "name=%s ci=%p\n", alg->ixt_name, ci); /* * alloc cipher context for this key */ cx = ci->realloc_context (NULL, ci, keylen); if (!cx) { printk(KERN_ERR "_capi_new_key(): " "NULL cx for \"%s\" cryptoapi algo\n" , alg->ixt_name); /* ci->unlock (); */ goto err; } if (ci->set_key (cx, key, keylen) < 0) { printk(KERN_ERR "_capi_new_key(): " "failed new_key() for \"%s\" cryptoapi algo\n" , alg->ixt_name); ci->wipe_context (cx); ci->free_context (cx); /* ci->unlock (); */ cx=NULL; }err: /* * unbind 1 lease if failed (bad key, ENOMEM, etc ...) */ if (!cx) _capi_ci_unbind(cptr); if (debug > 0) printk(KERN_DEBUG "klips_debug:_capi_new_key:" "name=%s key=%p keylen=%d cx=%p\n", alg->ixt_name, key, keylen, cx); return (__u8 *) cx;}/* * core encryption function: will use cx->ci to call actual cipher's * cbc function */static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { int error; struct cipher_context *cx=(struct cipher_context *)key_e; if (debug > 0) printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" "cx=%p key_e=%p " "in=%p out=%p ilen=%d iv=%p encrypt=%d\n" , cx , key_e , in, in, ilen, iv, encrypt); /* this _iv() functions seems to appear AFTER 2.4.18.1 */ if (encrypt) error = cx->ci->encrypt_atomic_iv (cx, in, in, ilen, iv); else error = cx->ci->decrypt_atomic_iv (cx, in, in, ilen, iv); if (debug > 0) printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" "error=%d\n" , error); return (error<0)? error : ilen;}/* * main initialization loop: for each cipher in list, do * 1) setup cryptoapi cipher else continue * 2) register ipsec_alg object * dont bind (lock) cipher if latebind specified, it will * get re-searched and locked at SA creation time (_new_key()) */static intsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) { struct ipsec_alg_capi_cipher *cptr; struct cipher_implementation *ci; /* foreach cipher in list ... */ for (cptr=clist;cptr->ciphername;cptr++) { /* * see if cipher has been disabled (0) or * if noauto set and not enabled (1) */ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) { if (debug>0) printk(KERN_INFO "setup_cipher_list(): " "ciphername=%s skipped at user request: " "noauto=%d parm[0]=%d parm[1]=%d\n" , cptr->ciphername , noauto , cptr->parm[0] , cptr->parm[1]); continue; } /* * use a temp ci to avoid touching cptr->ci, * if register ipsec_alg success then bind cipher */ ci = setup_cipher(cptr->ciphername); if (ci) { ci->lock(); if (debug > 0) printk(KERN_DEBUG "klips_debug:" "setup_cipher_list():" "ciphername=%s found\n" , cptr->ciphername); if (setup_ipsec_alg_capi_cipher(cptr, ci) == 0) { if (latebind==0) _capi_ci_bind(cptr, ci); } else { printk(KERN_ERR "klips_debug:" "setup_cipher_list():" "ciphername=%s failed ipsec_alg_register\n" , cptr->ciphername); } ci->unlock(); } } return 0;}/* * deregister ipsec_alg objects and unbind ciphers */static intunsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) { struct ipsec_alg_capi_cipher *cptr; /* foreach cipher in list ... */ for (cptr=clist;cptr->ciphername;cptr++) { if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { unregister_ipsec_alg_enc(&cptr->alg); if (latebind==0) _capi_ci_unbind(cptr); } } return 0;}/* * test loop for registered algos */static inttest_cipher_list (struct ipsec_alg_capi_cipher* clist) { int test_ret; struct ipsec_alg_capi_cipher *cptr; /* foreach cipher in list ... */ for (cptr=clist;cptr->ciphername;cptr++) { if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { test_ret=ipsec_alg_test( cptr->alg.ixt_alg_type, cptr->alg.ixt_alg_id, test); printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", cptr->alg.ixt_alg_type, cptr->alg.ixt_alg_id, test_ret); } } return 0;}IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ){ int ret, test_ret; if ((ret=setup_cipher_list(alg_capi_carray)) < 0) return -EPROTONOSUPPORT; if (ret==0 && test) { test_ret=test_cipher_list(alg_capi_carray); } return ret;}IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini ){ unsetup_cipher_list(alg_capi_carray); return;}#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifEXPORT_NO_SYMBOLS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -