1 /* 2 * Create default crypto algorithm instances. 3 * 4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the Free 8 * Software Foundation; either version 2 of the License, or (at your option) 9 * any later version. 10 * 11 */ 12 13 #include <linux/crypto.h> 14 #include <linux/ctype.h> 15 #include <linux/err.h> 16 #include <linux/init.h> 17 #include <linux/kthread.h> 18 #include <linux/module.h> 19 #include <linux/notifier.h> 20 #include <linux/rtnetlink.h> 21 #include <linux/sched.h> 22 #include <linux/string.h> 23 24 #include "internal.h" 25 26 struct cryptomgr_param { 27 struct rtattr *tb[CRYPTO_MAX_ATTRS + 2]; 28 29 struct { 30 struct rtattr attr; 31 struct crypto_attr_type data; 32 } type; 33 34 union { 35 struct rtattr attr; 36 struct { 37 struct rtattr attr; 38 struct crypto_attr_alg data; 39 } alg; 40 struct { 41 struct rtattr attr; 42 struct crypto_attr_u32 data; 43 } nu32; 44 } attrs[CRYPTO_MAX_ATTRS]; 45 46 char larval[CRYPTO_MAX_ALG_NAME]; 47 char template[CRYPTO_MAX_ALG_NAME]; 48 }; 49 50 static int cryptomgr_probe(void *data) 51 { 52 struct cryptomgr_param *param = data; 53 struct crypto_template *tmpl; 54 struct crypto_instance *inst; 55 int err; 56 57 tmpl = crypto_lookup_template(param->template); 58 if (!tmpl) 59 goto err; 60 61 do { 62 inst = tmpl->alloc(param->tb); 63 if (IS_ERR(inst)) 64 err = PTR_ERR(inst); 65 else if ((err = crypto_register_instance(tmpl, inst))) 66 tmpl->free(inst); 67 } while (err == -EAGAIN && !signal_pending(current)); 68 69 crypto_tmpl_put(tmpl); 70 71 if (err) 72 goto err; 73 74 out: 75 kfree(param); 76 module_put_and_exit(0); 77 78 err: 79 crypto_larval_error(param->larval, param->type.data.type, 80 param->type.data.mask); 81 goto out; 82 } 83 84 static int cryptomgr_schedule_probe(struct crypto_larval *larval) 85 { 86 struct task_struct *thread; 87 struct cryptomgr_param *param; 88 const char *name = larval->alg.cra_name; 89 const char *p; 90 unsigned int len; 91 int i; 92 93 if (!try_module_get(THIS_MODULE)) 94 goto err; 95 96 param = kzalloc(sizeof(*param), GFP_KERNEL); 97 if (!param) 98 goto err_put_module; 99 100 for (p = name; isalnum(*p) || *p == '-' || *p == '_'; p++) 101 ; 102 103 len = p - name; 104 if (!len || *p != '(') 105 goto err_free_param; 106 107 memcpy(param->template, name, len); 108 109 i = 0; 110 for (;;) { 111 int notnum = 0; 112 113 name = ++p; 114 len = 0; 115 116 for (; isalnum(*p) || *p == '-' || *p == '_'; p++) 117 notnum |= !isdigit(*p); 118 119 if (*p == '(') { 120 int recursion = 0; 121 122 for (;;) { 123 if (!*++p) 124 goto err_free_param; 125 if (*p == '(') 126 recursion++; 127 else if (*p == ')' && !recursion--) 128 break; 129 } 130 131 notnum = 1; 132 p++; 133 } 134 135 len = p - name; 136 if (!len) 137 goto err_free_param; 138 139 if (notnum) { 140 param->attrs[i].alg.attr.rta_len = 141 sizeof(param->attrs[i].alg); 142 param->attrs[i].alg.attr.rta_type = CRYPTOA_ALG; 143 memcpy(param->attrs[i].alg.data.name, name, len); 144 } else { 145 param->attrs[i].nu32.attr.rta_len = 146 sizeof(param->attrs[i].nu32); 147 param->attrs[i].nu32.attr.rta_type = CRYPTOA_U32; 148 param->attrs[i].nu32.data.num = 149 simple_strtol(name, NULL, 0); 150 } 151 152 param->tb[i + 1] = ¶m->attrs[i].attr; 153 i++; 154 155 if (i >= CRYPTO_MAX_ATTRS) 156 goto err_free_param; 157 158 if (*p == ')') 159 break; 160 161 if (*p != ',') 162 goto err_free_param; 163 } 164 165 if (!i) 166 goto err_free_param; 167 168 param->tb[i + 1] = NULL; 169 170 param->type.attr.rta_len = sizeof(param->type); 171 param->type.attr.rta_type = CRYPTOA_TYPE; 172 param->type.data.type = larval->alg.cra_flags; 173 param->type.data.mask = larval->mask; 174 param->tb[0] = ¶m->type.attr; 175 176 memcpy(param->larval, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); 177 178 thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); 179 if (IS_ERR(thread)) 180 goto err_free_param; 181 182 return NOTIFY_STOP; 183 184 err_free_param: 185 kfree(param); 186 err_put_module: 187 module_put(THIS_MODULE); 188 err: 189 return NOTIFY_OK; 190 } 191 192 static int cryptomgr_notify(struct notifier_block *this, unsigned long msg, 193 void *data) 194 { 195 switch (msg) { 196 case CRYPTO_MSG_ALG_REQUEST: 197 return cryptomgr_schedule_probe(data); 198 } 199 200 return NOTIFY_DONE; 201 } 202 203 static struct notifier_block cryptomgr_notifier = { 204 .notifier_call = cryptomgr_notify, 205 }; 206 207 static int __init cryptomgr_init(void) 208 { 209 int err; 210 211 err = testmgr_init(); 212 if (err) 213 return err; 214 215 err = crypto_register_notifier(&cryptomgr_notifier); 216 if (err) 217 goto free_testmgr; 218 219 return 0; 220 221 free_testmgr: 222 testmgr_exit(); 223 return err; 224 } 225 226 static void __exit cryptomgr_exit(void) 227 { 228 int err = crypto_unregister_notifier(&cryptomgr_notifier); 229 BUG_ON(err); 230 231 testmgr_exit(); 232 } 233 234 subsys_initcall(cryptomgr_init); 235 module_exit(cryptomgr_exit); 236 237 MODULE_LICENSE("GPL"); 238 MODULE_DESCRIPTION("Crypto Algorithm Manager"); 239