api.c (c51b6c8102a82239163c8c04e404c7cc2857b4be) | api.c (73d3864a4823abda19ebc4387b6ddcbf416e3a77) |
---|---|
1/* 2 * Scatterlist Cryptographic API. 3 * 4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 5 * Copyright (c) 2002 David S. Miller (davem@redhat.com) 6 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> 7 * 8 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> --- 41 unchanged lines hidden (view full) --- 50{ 51 struct module *module = alg->cra_module; 52 53 crypto_alg_put(alg); 54 module_put(module); 55} 56EXPORT_SYMBOL_GPL(crypto_mod_put); 57 | 1/* 2 * Scatterlist Cryptographic API. 3 * 4 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 5 * Copyright (c) 2002 David S. Miller (davem@redhat.com) 6 * Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au> 7 * 8 * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no> --- 41 unchanged lines hidden (view full) --- 50{ 51 struct module *module = alg->cra_module; 52 53 crypto_alg_put(alg); 54 module_put(module); 55} 56EXPORT_SYMBOL_GPL(crypto_mod_put); 57 |
58static inline int crypto_is_test_larval(struct crypto_larval *larval) 59{ 60 return larval->alg.cra_driver_name[0]; 61} 62 |
|
58static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, 59 u32 mask) 60{ 61 struct crypto_alg *q, *alg = NULL; 62 int best = -2; 63 64 list_for_each_entry(q, &crypto_alg_list, cra_list) { 65 int exact, fuzzy; 66 67 if (crypto_is_moribund(q)) 68 continue; 69 70 if ((q->cra_flags ^ type) & mask) 71 continue; 72 73 if (crypto_is_larval(q) && | 63static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, 64 u32 mask) 65{ 66 struct crypto_alg *q, *alg = NULL; 67 int best = -2; 68 69 list_for_each_entry(q, &crypto_alg_list, cra_list) { 70 int exact, fuzzy; 71 72 if (crypto_is_moribund(q)) 73 continue; 74 75 if ((q->cra_flags ^ type) & mask) 76 continue; 77 78 if (crypto_is_larval(q) && |
79 !crypto_is_test_larval((struct crypto_larval *)q) && |
|
74 ((struct crypto_larval *)q)->mask != mask) 75 continue; 76 77 exact = !strcmp(q->cra_driver_name, name); 78 fuzzy = !strcmp(q->cra_name, name); 79 if (!exact && !(fuzzy && q->cra_priority > best)) 80 continue; 81 --- 17 unchanged lines hidden (view full) --- 99 struct crypto_larval *larval = (void *)alg; 100 101 BUG_ON(!crypto_is_larval(alg)); 102 if (larval->adult) 103 crypto_mod_put(larval->adult); 104 kfree(larval); 105} 106 | 80 ((struct crypto_larval *)q)->mask != mask) 81 continue; 82 83 exact = !strcmp(q->cra_driver_name, name); 84 fuzzy = !strcmp(q->cra_name, name); 85 if (!exact && !(fuzzy && q->cra_priority > best)) 86 continue; 87 --- 17 unchanged lines hidden (view full) --- 105 struct crypto_larval *larval = (void *)alg; 106 107 BUG_ON(!crypto_is_larval(alg)); 108 if (larval->adult) 109 crypto_mod_put(larval->adult); 110 kfree(larval); 111} 112 |
107static struct crypto_alg *crypto_larval_alloc(const char *name, u32 type, 108 u32 mask) | 113struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask) |
109{ | 114{ |
110 struct crypto_alg *alg; | |
111 struct crypto_larval *larval; 112 113 larval = kzalloc(sizeof(*larval), GFP_KERNEL); 114 if (!larval) 115 return ERR_PTR(-ENOMEM); 116 117 larval->mask = mask; 118 larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type; 119 larval->alg.cra_priority = -1; 120 larval->alg.cra_destroy = crypto_larval_destroy; 121 | 115 struct crypto_larval *larval; 116 117 larval = kzalloc(sizeof(*larval), GFP_KERNEL); 118 if (!larval) 119 return ERR_PTR(-ENOMEM); 120 121 larval->mask = mask; 122 larval->alg.cra_flags = CRYPTO_ALG_LARVAL | type; 123 larval->alg.cra_priority = -1; 124 larval->alg.cra_destroy = crypto_larval_destroy; 125 |
122 atomic_set(&larval->alg.cra_refcnt, 2); | |
123 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME); 124 init_completion(&larval->completion); 125 | 126 strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME); 127 init_completion(&larval->completion); 128 |
129 return larval; 130} 131EXPORT_SYMBOL_GPL(crypto_larval_alloc); 132 133static struct crypto_alg *crypto_larval_add(const char *name, u32 type, 134 u32 mask) 135{ 136 struct crypto_alg *alg; 137 struct crypto_larval *larval; 138 139 larval = crypto_larval_alloc(name, type, mask); 140 if (IS_ERR(larval)) 141 return ERR_CAST(larval); 142 143 atomic_set(&larval->alg.cra_refcnt, 2); 144 |
|
126 down_write(&crypto_alg_sem); 127 alg = __crypto_alg_lookup(name, type, mask); 128 if (!alg) { 129 alg = &larval->alg; 130 list_add(&alg->cra_list, &crypto_alg_list); 131 } 132 up_write(&crypto_alg_sem); 133 --- 13 unchanged lines hidden (view full) --- 147 complete_all(&larval->completion); 148 crypto_alg_put(alg); 149} 150EXPORT_SYMBOL_GPL(crypto_larval_kill); 151 152static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) 153{ 154 struct crypto_larval *larval = (void *)alg; | 145 down_write(&crypto_alg_sem); 146 alg = __crypto_alg_lookup(name, type, mask); 147 if (!alg) { 148 alg = &larval->alg; 149 list_add(&alg->cra_list, &crypto_alg_list); 150 } 151 up_write(&crypto_alg_sem); 152 --- 13 unchanged lines hidden (view full) --- 166 complete_all(&larval->completion); 167 crypto_alg_put(alg); 168} 169EXPORT_SYMBOL_GPL(crypto_larval_kill); 170 171static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) 172{ 173 struct crypto_larval *larval = (void *)alg; |
174 long timeout; |
|
155 | 175 |
156 wait_for_completion_interruptible_timeout(&larval->completion, 60 * HZ); | 176 timeout = wait_for_completion_interruptible_timeout( 177 &larval->completion, 60 * HZ); 178 |
157 alg = larval->adult; | 179 alg = larval->adult; |
158 if (alg) { 159 if (!crypto_mod_get(alg)) 160 alg = ERR_PTR(-EAGAIN); 161 } else | 180 if (timeout < 0) 181 alg = ERR_PTR(-EINTR); 182 else if (!timeout) 183 alg = ERR_PTR(-ETIMEDOUT); 184 else if (!alg) |
162 alg = ERR_PTR(-ENOENT); | 185 alg = ERR_PTR(-ENOENT); |
186 else if (crypto_is_test_larval(larval) && 187 !(alg->cra_flags & CRYPTO_ALG_TESTED)) 188 alg = ERR_PTR(-EAGAIN); 189 else if (!crypto_mod_get(alg)) 190 alg = ERR_PTR(-EAGAIN); |
|
163 crypto_mod_put(&larval->alg); 164 165 return alg; 166} 167 168struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask) 169{ 170 struct crypto_alg *alg; --- 16 unchanged lines hidden (view full) --- 187 mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); 188 type &= mask; 189 190 alg = try_then_request_module(crypto_alg_lookup(name, type, mask), 191 name); 192 if (alg) 193 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; 194 | 191 crypto_mod_put(&larval->alg); 192 193 return alg; 194} 195 196struct crypto_alg *crypto_alg_lookup(const char *name, u32 type, u32 mask) 197{ 198 struct crypto_alg *alg; --- 16 unchanged lines hidden (view full) --- 215 mask &= ~(CRYPTO_ALG_LARVAL | CRYPTO_ALG_DEAD); 216 type &= mask; 217 218 alg = try_then_request_module(crypto_alg_lookup(name, type, mask), 219 name); 220 if (alg) 221 return crypto_is_larval(alg) ? crypto_larval_wait(alg) : alg; 222 |
195 return crypto_larval_alloc(name, type, mask); | 223 return crypto_larval_add(name, type, mask); |
196} 197EXPORT_SYMBOL_GPL(crypto_larval_lookup); 198 | 224} 225EXPORT_SYMBOL_GPL(crypto_larval_lookup); 226 |
227int crypto_probing_notify(unsigned long val, void *v) 228{ 229 int ok; 230 231 ok = blocking_notifier_call_chain(&crypto_chain, val, v); 232 if (ok == NOTIFY_DONE) { 233 request_module("cryptomgr"); 234 ok = blocking_notifier_call_chain(&crypto_chain, val, v); 235 } 236 237 return ok; 238} 239EXPORT_SYMBOL_GPL(crypto_probing_notify); 240 |
|
199struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) 200{ 201 struct crypto_alg *alg; 202 struct crypto_alg *larval; 203 int ok; 204 | 241struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask) 242{ 243 struct crypto_alg *alg; 244 struct crypto_alg *larval; 245 int ok; 246 |
247 if (!(mask & CRYPTO_ALG_TESTED)) { 248 type |= CRYPTO_ALG_TESTED; 249 mask |= CRYPTO_ALG_TESTED; 250 } 251 |
|
205 larval = crypto_larval_lookup(name, type, mask); 206 if (IS_ERR(larval) || !crypto_is_larval(larval)) 207 return larval; 208 | 252 larval = crypto_larval_lookup(name, type, mask); 253 if (IS_ERR(larval) || !crypto_is_larval(larval)) 254 return larval; 255 |
209 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval); 210 if (ok == NOTIFY_DONE) { 211 request_module("cryptomgr"); 212 ok = crypto_notify(CRYPTO_MSG_ALG_REQUEST, larval); 213 } | 256 ok = crypto_probing_notify(CRYPTO_MSG_ALG_REQUEST, larval); |
214 215 if (ok == NOTIFY_STOP) 216 alg = crypto_larval_wait(larval); 217 else { 218 crypto_mod_put(larval); 219 alg = ERR_PTR(-ENOENT); 220 } 221 crypto_larval_kill(larval); --- 233 unchanged lines hidden --- | 257 258 if (ok == NOTIFY_STOP) 259 alg = crypto_larval_wait(larval); 260 else { 261 crypto_mod_put(larval); 262 alg = ERR_PTR(-ENOENT); 263 } 264 crypto_larval_kill(larval); --- 233 unchanged lines hidden --- |