Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* 3 : : * Create default crypto algorithm instances. 4 : : * 5 : : * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 6 : : */ 7 : : 8 : : #include <crypto/internal/aead.h> 9 : : #include <linux/completion.h> 10 : : #include <linux/ctype.h> 11 : : #include <linux/err.h> 12 : : #include <linux/init.h> 13 : : #include <linux/kthread.h> 14 : : #include <linux/module.h> 15 : : #include <linux/notifier.h> 16 : : #include <linux/rtnetlink.h> 17 : : #include <linux/sched/signal.h> 18 : : #include <linux/slab.h> 19 : : #include <linux/string.h> 20 : : 21 : : #include "internal.h" 22 : : 23 : : struct cryptomgr_param { 24 : : struct rtattr *tb[CRYPTO_MAX_ATTRS + 2]; 25 : : 26 : : struct { 27 : : struct rtattr attr; 28 : : struct crypto_attr_type data; 29 : : } type; 30 : : 31 : : union { 32 : : struct rtattr attr; 33 : : struct { 34 : : struct rtattr attr; 35 : : struct crypto_attr_alg data; 36 : : } alg; 37 : : struct { 38 : : struct rtattr attr; 39 : : struct crypto_attr_u32 data; 40 : : } nu32; 41 : : } attrs[CRYPTO_MAX_ATTRS]; 42 : : 43 : : char template[CRYPTO_MAX_ALG_NAME]; 44 : : 45 : : struct crypto_larval *larval; 46 : : 47 : : u32 otype; 48 : : u32 omask; 49 : : }; 50 : : 51 : : struct crypto_test_param { 52 : : char driver[CRYPTO_MAX_ALG_NAME]; 53 : : char alg[CRYPTO_MAX_ALG_NAME]; 54 : : u32 type; 55 : : }; 56 : : 57 : 78 : static int cryptomgr_probe(void *data) 58 : : { 59 : 78 : struct cryptomgr_param *param = data; 60 : 78 : struct crypto_template *tmpl; 61 : 78 : int err; 62 : : 63 : 78 : tmpl = crypto_lookup_template(param->template); 64 [ - + ]: 78 : if (!tmpl) 65 : 0 : goto out; 66 : : 67 : 78 : do { 68 : 78 : err = tmpl->create(tmpl, param->tb); 69 [ - + - - ]: 78 : } while (err == -EAGAIN && !signal_pending(current)); 70 : : 71 : 78 : crypto_tmpl_put(tmpl); 72 : : 73 : 78 : out: 74 : 78 : complete_all(¶m->larval->completion); 75 : 78 : crypto_alg_put(¶m->larval->alg); 76 : 78 : kfree(param); 77 : 78 : module_put_and_exit(0); 78 : : } 79 : : 80 : 78 : static int cryptomgr_schedule_probe(struct crypto_larval *larval) 81 : : { 82 : 78 : struct task_struct *thread; 83 : 78 : struct cryptomgr_param *param; 84 : 78 : const char *name = larval->alg.cra_name; 85 : 78 : const char *p; 86 : 78 : unsigned int len; 87 : 78 : int i; 88 : : 89 [ - + ]: 78 : if (!try_module_get(THIS_MODULE)) 90 : 0 : goto err; 91 : : 92 : 78 : param = kzalloc(sizeof(*param), GFP_KERNEL); 93 [ - + ]: 78 : if (!param) 94 : 0 : goto err_put_module; 95 : : 96 [ + + - + : 702 : for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) - + ] 97 : 624 : ; 98 : : 99 : 78 : len = p - name; 100 [ + - - + ]: 78 : if (!len || *p != '(') 101 : 0 : goto err_free_param; 102 : : 103 : 78 : memcpy(param->template, name, len); 104 : : 105 : 78 : i = 0; 106 : 156 : for (;;) { 107 : 156 : int notnum = 0; 108 : : 109 : 156 : name = ++p; 110 : : 111 [ + + - + : 858 : for (; isalnum(*p) || *p == '-' || *p == '_'; p++) - + ] 112 : 702 : notnum |= !isdigit(*p); 113 : : 114 [ - + ]: 156 : if (*p == '(') { 115 : : int recursion = 0; 116 : : 117 : 0 : for (;;) { 118 [ # # ]: 0 : if (!*++p) 119 : 0 : goto err_free_param; 120 [ # # ]: 0 : if (*p == '(') 121 : 0 : recursion++; 122 [ # # # # ]: 0 : else if (*p == ')' && !recursion--) 123 : : break; 124 : : } 125 : : 126 : 0 : notnum = 1; 127 : 0 : p++; 128 : : } 129 : : 130 : 156 : len = p - name; 131 [ - + ]: 156 : if (!len) 132 : 0 : goto err_free_param; 133 : : 134 [ + - ]: 156 : if (notnum) { 135 : 156 : param->attrs[i].alg.attr.rta_len = 136 : : sizeof(param->attrs[i].alg); 137 : 156 : param->attrs[i].alg.attr.rta_type = CRYPTOA_ALG; 138 : 156 : memcpy(param->attrs[i].alg.data.name, name, len); 139 : : } else { 140 : 0 : param->attrs[i].nu32.attr.rta_len = 141 : : sizeof(param->attrs[i].nu32); 142 : 0 : param->attrs[i].nu32.attr.rta_type = CRYPTOA_U32; 143 : 0 : param->attrs[i].nu32.data.num = 144 : 0 : simple_strtol(name, NULL, 0); 145 : : } 146 : : 147 : 156 : param->tb[i + 1] = ¶m->attrs[i].attr; 148 : 156 : i++; 149 : : 150 [ - + ]: 156 : if (i >= CRYPTO_MAX_ATTRS) 151 : 0 : goto err_free_param; 152 : : 153 [ + + ]: 156 : if (*p == ')') 154 : : break; 155 : : 156 [ + - ]: 78 : if (*p != ',') 157 : 0 : goto err_free_param; 158 : : } 159 : : 160 : 78 : if (!i) 161 : : goto err_free_param; 162 : : 163 : 78 : param->tb[i + 1] = NULL; 164 : : 165 : 78 : param->type.attr.rta_len = sizeof(param->type); 166 : 78 : param->type.attr.rta_type = CRYPTOA_TYPE; 167 : 78 : param->type.data.type = larval->alg.cra_flags & ~CRYPTO_ALG_TESTED; 168 : 78 : param->type.data.mask = larval->mask & ~CRYPTO_ALG_TESTED; 169 : 78 : param->tb[0] = ¶m->type.attr; 170 : : 171 : 78 : param->otype = larval->alg.cra_flags; 172 : 78 : param->omask = larval->mask; 173 : : 174 : 78 : crypto_alg_get(&larval->alg); 175 : 78 : param->larval = larval; 176 : : 177 [ + - ]: 78 : thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe"); 178 [ - + ]: 78 : if (IS_ERR(thread)) 179 : 0 : goto err_put_larval; 180 : : 181 : 78 : wait_for_completion_interruptible(&larval->completion); 182 : : 183 : 78 : return NOTIFY_STOP; 184 : : 185 : : err_put_larval: 186 : 0 : crypto_alg_put(&larval->alg); 187 : 0 : err_free_param: 188 : 0 : kfree(param); 189 : 0 : err_put_module: 190 : 0 : module_put(THIS_MODULE); 191 : : err: 192 : : return NOTIFY_OK; 193 : : } 194 : : 195 : 1872 : static int cryptomgr_test(void *data) 196 : : { 197 : 1872 : struct crypto_test_param *param = data; 198 : 1872 : u32 type = param->type; 199 : 1872 : int err = 0; 200 : : 201 : : #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS 202 : 1872 : goto skiptest; 203 : : #endif 204 : : 205 : : if (type & CRYPTO_ALG_TESTED) 206 : : goto skiptest; 207 : : 208 : : err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED); 209 : : 210 : : skiptest: 211 : 1872 : crypto_alg_tested(param->driver, err); 212 : : 213 : 1872 : kfree(param); 214 : 1872 : module_put_and_exit(0); 215 : : } 216 : : 217 : 1872 : static int cryptomgr_schedule_test(struct crypto_alg *alg) 218 : : { 219 : 1872 : struct task_struct *thread; 220 : 1872 : struct crypto_test_param *param; 221 : 1872 : u32 type; 222 : : 223 [ - + ]: 1872 : if (!try_module_get(THIS_MODULE)) 224 : 0 : goto err; 225 : : 226 : 1872 : param = kzalloc(sizeof(*param), GFP_KERNEL); 227 [ - + ]: 1872 : if (!param) 228 : 0 : goto err_put_module; 229 : : 230 : 1872 : memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver)); 231 : 1872 : memcpy(param->alg, alg->cra_name, sizeof(param->alg)); 232 : 1872 : type = alg->cra_flags; 233 : : 234 : : /* Do not test internal algorithms. */ 235 [ - + ]: 1872 : if (type & CRYPTO_ALG_INTERNAL) 236 : 0 : type |= CRYPTO_ALG_TESTED; 237 : : 238 : 1872 : param->type = type; 239 : : 240 [ + - ]: 1872 : thread = kthread_run(cryptomgr_test, param, "cryptomgr_test"); 241 [ - + ]: 1872 : if (IS_ERR(thread)) 242 : 0 : goto err_free_param; 243 : : 244 : : return NOTIFY_STOP; 245 : : 246 : : err_free_param: 247 : 0 : kfree(param); 248 : 0 : err_put_module: 249 : 0 : module_put(THIS_MODULE); 250 : : err: 251 : : return NOTIFY_OK; 252 : : } 253 : : 254 : 5694 : static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, 255 : : void *data) 256 : : { 257 [ + + + ]: 5694 : switch (msg) { 258 : 78 : case CRYPTO_MSG_ALG_REQUEST: 259 : 78 : return cryptomgr_schedule_probe(data); 260 : 1872 : case CRYPTO_MSG_ALG_REGISTER: 261 : 1872 : return cryptomgr_schedule_test(data); 262 : : case CRYPTO_MSG_ALG_LOADED: 263 : : break; 264 : : } 265 : : 266 : : return NOTIFY_DONE; 267 : : } 268 : : 269 : : static struct notifier_block cryptomgr_notifier = { 270 : : .notifier_call = cryptomgr_notify, 271 : : }; 272 : : 273 : 78 : static int __init cryptomgr_init(void) 274 : : { 275 : 78 : return crypto_register_notifier(&cryptomgr_notifier); 276 : : } 277 : : 278 : 0 : static void __exit cryptomgr_exit(void) 279 : : { 280 : 0 : int err = crypto_unregister_notifier(&cryptomgr_notifier); 281 [ # # ]: 0 : BUG_ON(err); 282 : 0 : } 283 : : 284 : : /* 285 : : * This is arch_initcall() so that the crypto self-tests are run on algorithms 286 : : * registered early by subsys_initcall(). subsys_initcall() is needed for 287 : : * generic implementations so that they're available for comparison tests when 288 : : * other implementations are registered later by module_init(). 289 : : */ 290 : : arch_initcall(cryptomgr_init); 291 : : module_exit(cryptomgr_exit); 292 : : 293 : : MODULE_LICENSE("GPL"); 294 : : MODULE_DESCRIPTION("Crypto Algorithm Manager");