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 : 404 : static int cryptomgr_probe(void *data) 58 : : { 59 : : struct cryptomgr_param *param = data; 60 : : struct crypto_template *tmpl; 61 : : struct crypto_instance *inst; 62 : : int err; 63 : : 64 : 404 : tmpl = crypto_lookup_template(param->template); 65 [ + - ]: 404 : if (!tmpl) 66 : : goto out; 67 : : 68 : : do { 69 [ + - ]: 404 : if (tmpl->create) { 70 : 404 : err = tmpl->create(tmpl, param->tb); 71 : 404 : continue; 72 : : } 73 : : 74 : 0 : inst = tmpl->alloc(param->tb); 75 [ # # ]: 0 : if (IS_ERR(inst)) 76 : : err = PTR_ERR(inst); 77 [ # # ]: 0 : else if ((err = crypto_register_instance(tmpl, inst))) 78 : 0 : tmpl->free(inst); 79 [ - + # # ]: 404 : } while (err == -EAGAIN && !signal_pending(current)); 80 : : 81 : : crypto_tmpl_put(tmpl); 82 : : 83 : : out: 84 : 404 : complete_all(¶m->larval->completion); 85 : 404 : crypto_alg_put(¶m->larval->alg); 86 : 404 : kfree(param); 87 : 404 : module_put_and_exit(0); 88 : : } 89 : : 90 : 404 : static int cryptomgr_schedule_probe(struct crypto_larval *larval) 91 : : { 92 : : struct task_struct *thread; 93 : : struct cryptomgr_param *param; 94 : 404 : const char *name = larval->alg.cra_name; 95 : : const char *p; 96 : : unsigned int len; 97 : : int i; 98 : : 99 [ + - ]: 404 : if (!try_module_get(THIS_MODULE)) 100 : : goto err; 101 : : 102 : 404 : param = kzalloc(sizeof(*param), GFP_KERNEL); 103 [ + - ]: 404 : if (!param) 104 : : goto err_put_module; 105 : : 106 [ + + - + : 3232 : for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) - + ] 107 : : ; 108 : : 109 : 404 : len = p - name; 110 [ + - + - ]: 404 : if (!len || *p != '(') 111 : : goto err_free_param; 112 : : 113 : 404 : memcpy(param->template, name, len); 114 : : 115 : : i = 0; 116 : : for (;;) { 117 : : int notnum = 0; 118 : : 119 : 808 : name = ++p; 120 : : 121 [ + + - + : 4444 : for (; isalnum(*p) || *p == '-' || *p == '_'; p++) - + ] 122 : 3636 : notnum |= !isdigit(*p); 123 : : 124 [ - + ]: 808 : if (*p == '(') { 125 : : int recursion = 0; 126 : : 127 : : for (;;) { 128 [ # # ]: 0 : if (!*++p) 129 : : goto err_free_param; 130 [ # # ]: 0 : if (*p == '(') 131 : 0 : recursion++; 132 [ # # # # ]: 0 : else if (*p == ')' && !recursion--) 133 : : break; 134 : : } 135 : : 136 : : notnum = 1; 137 : 0 : p++; 138 : : } 139 : : 140 : 808 : len = p - name; 141 [ + - ]: 808 : if (!len) 142 : : goto err_free_param; 143 : : 144 [ + - ]: 808 : if (notnum) { 145 : 808 : param->attrs[i].alg.attr.rta_len = 146 : : sizeof(param->attrs[i].alg); 147 : 808 : param->attrs[i].alg.attr.rta_type = CRYPTOA_ALG; 148 : 808 : memcpy(param->attrs[i].alg.data.name, name, len); 149 : : } else { 150 : 0 : param->attrs[i].nu32.attr.rta_len = 151 : : sizeof(param->attrs[i].nu32); 152 : 0 : param->attrs[i].nu32.attr.rta_type = CRYPTOA_U32; 153 : 0 : param->attrs[i].nu32.data.num = 154 : 0 : simple_strtol(name, NULL, 0); 155 : : } 156 : : 157 : 808 : param->tb[i + 1] = ¶m->attrs[i].attr; 158 : : i++; 159 : : 160 [ + - ]: 808 : if (i >= CRYPTO_MAX_ATTRS) 161 : : goto err_free_param; 162 : : 163 [ + + ]: 808 : if (*p == ')') 164 : : break; 165 : : 166 [ + - ]: 404 : if (*p != ',') 167 : : goto err_free_param; 168 : : } 169 : : 170 [ + - ]: 404 : if (!i) 171 : : goto err_free_param; 172 : : 173 : 404 : param->tb[i + 1] = NULL; 174 : : 175 : 404 : param->type.attr.rta_len = sizeof(param->type); 176 : 404 : param->type.attr.rta_type = CRYPTOA_TYPE; 177 : 404 : param->type.data.type = larval->alg.cra_flags & ~CRYPTO_ALG_TESTED; 178 : 404 : param->type.data.mask = larval->mask & ~CRYPTO_ALG_TESTED; 179 : 404 : param->tb[0] = ¶m->type.attr; 180 : : 181 : 404 : param->otype = larval->alg.cra_flags; 182 : 404 : param->omask = larval->mask; 183 : : 184 : : crypto_alg_get(&larval->alg); 185 : 404 : param->larval = larval; 186 : : 187 [ + - ]: 808 : thread = kthread_run(cryptomgr_probe, param, "cryptomgr_probe"); 188 [ - + ]: 404 : if (IS_ERR(thread)) 189 : : goto err_put_larval; 190 : : 191 : : return NOTIFY_STOP; 192 : : 193 : : err_put_larval: 194 : 0 : crypto_alg_put(&larval->alg); 195 : : err_free_param: 196 : 0 : kfree(param); 197 : : err_put_module: 198 : 0 : module_put(THIS_MODULE); 199 : : err: 200 : : return NOTIFY_OK; 201 : : } 202 : : 203 : 8080 : static int cryptomgr_test(void *data) 204 : : { 205 : : struct crypto_test_param *param = data; 206 : : u32 type = param->type; 207 : : int err = 0; 208 : : 209 : : #ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS 210 : : goto skiptest; 211 : : #endif 212 : : 213 : : if (type & CRYPTO_ALG_TESTED) 214 : : goto skiptest; 215 : : 216 : : err = alg_test(param->driver, param->alg, type, CRYPTO_ALG_TESTED); 217 : : 218 : : skiptest: 219 : 8080 : crypto_alg_tested(param->driver, err); 220 : : 221 : 8080 : kfree(param); 222 : 8080 : module_put_and_exit(0); 223 : : } 224 : : 225 : 8080 : static int cryptomgr_schedule_test(struct crypto_alg *alg) 226 : : { 227 : : struct task_struct *thread; 228 : : struct crypto_test_param *param; 229 : : u32 type; 230 : : 231 [ + - ]: 8080 : if (!try_module_get(THIS_MODULE)) 232 : : goto err; 233 : : 234 : 8080 : param = kzalloc(sizeof(*param), GFP_KERNEL); 235 [ + - ]: 8080 : if (!param) 236 : : goto err_put_module; 237 : : 238 : 8080 : memcpy(param->driver, alg->cra_driver_name, sizeof(param->driver)); 239 : 8080 : memcpy(param->alg, alg->cra_name, sizeof(param->alg)); 240 : 8080 : type = alg->cra_flags; 241 : : 242 : : /* Do not test internal algorithms. */ 243 [ - + ]: 8080 : if (type & CRYPTO_ALG_INTERNAL) 244 : 0 : type |= CRYPTO_ALG_TESTED; 245 : : 246 : 8080 : param->type = type; 247 : : 248 [ + - ]: 16160 : thread = kthread_run(cryptomgr_test, param, "cryptomgr_test"); 249 [ - + ]: 8080 : if (IS_ERR(thread)) 250 : : goto err_free_param; 251 : : 252 : : return NOTIFY_STOP; 253 : : 254 : : err_free_param: 255 : 0 : kfree(param); 256 : : err_put_module: 257 : 0 : module_put(THIS_MODULE); 258 : : err: 259 : : return NOTIFY_OK; 260 : : } 261 : : 262 : 16564 : static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, 263 : : void *data) 264 : : { 265 [ + + + ]: 16564 : switch (msg) { 266 : : case CRYPTO_MSG_ALG_REQUEST: 267 : 404 : return cryptomgr_schedule_probe(data); 268 : : case CRYPTO_MSG_ALG_REGISTER: 269 : 8080 : return cryptomgr_schedule_test(data); 270 : : case CRYPTO_MSG_ALG_LOADED: 271 : : break; 272 : : } 273 : : 274 : : return NOTIFY_DONE; 275 : : } 276 : : 277 : : static struct notifier_block cryptomgr_notifier = { 278 : : .notifier_call = cryptomgr_notify, 279 : : }; 280 : : 281 : 404 : static int __init cryptomgr_init(void) 282 : : { 283 : 404 : return crypto_register_notifier(&cryptomgr_notifier); 284 : : } 285 : : 286 : 0 : static void __exit cryptomgr_exit(void) 287 : : { 288 : 0 : int err = crypto_unregister_notifier(&cryptomgr_notifier); 289 [ # # ]: 0 : BUG_ON(err); 290 : 0 : } 291 : : 292 : : /* 293 : : * This is arch_initcall() so that the crypto self-tests are run on algorithms 294 : : * registered early by subsys_initcall(). subsys_initcall() is needed for 295 : : * generic implementations so that they're available for comparison tests when 296 : : * other implementations are registered later by module_init(). 297 : : */ 298 : : arch_initcall(cryptomgr_init); 299 : : module_exit(cryptomgr_exit); 300 : : 301 : : MODULE_LICENSE("GPL"); 302 : : MODULE_DESCRIPTION("Crypto Algorithm Manager");