1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Crypto user configuration API. 4 * 5 * Copyright (C) 2017-2018 Corentin Labbe <clabbe@baylibre.com> 6 * 7 */ 8 9 #include <linux/crypto.h> 10 #include <linux/cryptouser.h> 11 #include <linux/sched.h> 12 #include <net/netlink.h> 13 #include <crypto/internal/skcipher.h> 14 #include <crypto/internal/rng.h> 15 #include <crypto/akcipher.h> 16 #include <crypto/kpp.h> 17 #include <crypto/internal/cryptouser.h> 18 19 #include "internal.h" 20 21 #define null_terminated(x) (strnlen(x, sizeof(x)) < sizeof(x)) 22 23 static DEFINE_MUTEX(crypto_cfg_mutex); 24 25 extern struct sock *crypto_nlsk; 26 27 struct crypto_dump_info { 28 struct sk_buff *in_skb; 29 struct sk_buff *out_skb; 30 u32 nlmsg_seq; 31 u16 nlmsg_flags; 32 }; 33 34 static int crypto_report_aead(struct sk_buff *skb, struct crypto_alg *alg) 35 { 36 struct crypto_stat raead; 37 u64 v64; 38 u32 v32; 39 40 memset(&raead, 0, sizeof(raead)); 41 42 strncpy(raead.type, "aead", sizeof(raead.type)); 43 44 v32 = atomic_read(&alg->encrypt_cnt); 45 raead.stat_encrypt_cnt = v32; 46 v64 = atomic64_read(&alg->encrypt_tlen); 47 raead.stat_encrypt_tlen = v64; 48 v32 = atomic_read(&alg->decrypt_cnt); 49 raead.stat_decrypt_cnt = v32; 50 v64 = atomic64_read(&alg->decrypt_tlen); 51 raead.stat_decrypt_tlen = v64; 52 v32 = atomic_read(&alg->aead_err_cnt); 53 raead.stat_aead_err_cnt = v32; 54 55 if (nla_put(skb, CRYPTOCFGA_STAT_AEAD, 56 sizeof(struct crypto_stat), &raead)) 57 goto nla_put_failure; 58 return 0; 59 60 nla_put_failure: 61 return -EMSGSIZE; 62 } 63 64 static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) 65 { 66 struct crypto_stat rcipher; 67 u64 v64; 68 u32 v32; 69 70 memset(&rcipher, 0, sizeof(rcipher)); 71 72 strlcpy(rcipher.type, "cipher", sizeof(rcipher.type)); 73 74 v32 = atomic_read(&alg->encrypt_cnt); 75 rcipher.stat_encrypt_cnt = v32; 76 v64 = atomic64_read(&alg->encrypt_tlen); 77 rcipher.stat_encrypt_tlen = v64; 78 v32 = atomic_read(&alg->decrypt_cnt); 79 rcipher.stat_decrypt_cnt = v32; 80 v64 = atomic64_read(&alg->decrypt_tlen); 81 rcipher.stat_decrypt_tlen = v64; 82 v32 = atomic_read(&alg->cipher_err_cnt); 83 rcipher.stat_cipher_err_cnt = v32; 84 85 if (nla_put(skb, CRYPTOCFGA_STAT_CIPHER, 86 sizeof(struct crypto_stat), &rcipher)) 87 goto nla_put_failure; 88 return 0; 89 90 nla_put_failure: 91 return -EMSGSIZE; 92 } 93 94 static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg) 95 { 96 struct crypto_stat rcomp; 97 u64 v64; 98 u32 v32; 99 100 memset(&rcomp, 0, sizeof(rcomp)); 101 102 strlcpy(rcomp.type, "compression", sizeof(rcomp.type)); 103 v32 = atomic_read(&alg->compress_cnt); 104 rcomp.stat_compress_cnt = v32; 105 v64 = atomic64_read(&alg->compress_tlen); 106 rcomp.stat_compress_tlen = v64; 107 v32 = atomic_read(&alg->decompress_cnt); 108 rcomp.stat_decompress_cnt = v32; 109 v64 = atomic64_read(&alg->decompress_tlen); 110 rcomp.stat_decompress_tlen = v64; 111 v32 = atomic_read(&alg->cipher_err_cnt); 112 rcomp.stat_compress_err_cnt = v32; 113 114 if (nla_put(skb, CRYPTOCFGA_STAT_COMPRESS, 115 sizeof(struct crypto_stat), &rcomp)) 116 goto nla_put_failure; 117 return 0; 118 119 nla_put_failure: 120 return -EMSGSIZE; 121 } 122 123 static int crypto_report_acomp(struct sk_buff *skb, struct crypto_alg *alg) 124 { 125 struct crypto_stat racomp; 126 u64 v64; 127 u32 v32; 128 129 memset(&racomp, 0, sizeof(racomp)); 130 131 strlcpy(racomp.type, "acomp", sizeof(racomp.type)); 132 v32 = atomic_read(&alg->compress_cnt); 133 racomp.stat_compress_cnt = v32; 134 v64 = atomic64_read(&alg->compress_tlen); 135 racomp.stat_compress_tlen = v64; 136 v32 = atomic_read(&alg->decompress_cnt); 137 racomp.stat_decompress_cnt = v32; 138 v64 = atomic64_read(&alg->decompress_tlen); 139 racomp.stat_decompress_tlen = v64; 140 v32 = atomic_read(&alg->cipher_err_cnt); 141 racomp.stat_compress_err_cnt = v32; 142 143 if (nla_put(skb, CRYPTOCFGA_STAT_ACOMP, 144 sizeof(struct crypto_stat), &racomp)) 145 goto nla_put_failure; 146 return 0; 147 148 nla_put_failure: 149 return -EMSGSIZE; 150 } 151 152 static int crypto_report_akcipher(struct sk_buff *skb, struct crypto_alg *alg) 153 { 154 struct crypto_stat rakcipher; 155 u64 v64; 156 u32 v32; 157 158 memset(&rakcipher, 0, sizeof(rakcipher)); 159 160 strncpy(rakcipher.type, "akcipher", sizeof(rakcipher.type)); 161 v32 = atomic_read(&alg->encrypt_cnt); 162 rakcipher.stat_encrypt_cnt = v32; 163 v64 = atomic64_read(&alg->encrypt_tlen); 164 rakcipher.stat_encrypt_tlen = v64; 165 v32 = atomic_read(&alg->decrypt_cnt); 166 rakcipher.stat_decrypt_cnt = v32; 167 v64 = atomic64_read(&alg->decrypt_tlen); 168 rakcipher.stat_decrypt_tlen = v64; 169 v32 = atomic_read(&alg->sign_cnt); 170 rakcipher.stat_sign_cnt = v32; 171 v32 = atomic_read(&alg->verify_cnt); 172 rakcipher.stat_verify_cnt = v32; 173 v32 = atomic_read(&alg->akcipher_err_cnt); 174 rakcipher.stat_akcipher_err_cnt = v32; 175 176 if (nla_put(skb, CRYPTOCFGA_STAT_AKCIPHER, 177 sizeof(struct crypto_stat), &rakcipher)) 178 goto nla_put_failure; 179 return 0; 180 181 nla_put_failure: 182 return -EMSGSIZE; 183 } 184 185 static int crypto_report_kpp(struct sk_buff *skb, struct crypto_alg *alg) 186 { 187 struct crypto_stat rkpp; 188 u32 v; 189 190 memset(&rkpp, 0, sizeof(rkpp)); 191 192 strlcpy(rkpp.type, "kpp", sizeof(rkpp.type)); 193 194 v = atomic_read(&alg->setsecret_cnt); 195 rkpp.stat_setsecret_cnt = v; 196 v = atomic_read(&alg->generate_public_key_cnt); 197 rkpp.stat_generate_public_key_cnt = v; 198 v = atomic_read(&alg->compute_shared_secret_cnt); 199 rkpp.stat_compute_shared_secret_cnt = v; 200 v = atomic_read(&alg->kpp_err_cnt); 201 rkpp.stat_kpp_err_cnt = v; 202 203 if (nla_put(skb, CRYPTOCFGA_STAT_KPP, 204 sizeof(struct crypto_stat), &rkpp)) 205 goto nla_put_failure; 206 return 0; 207 208 nla_put_failure: 209 return -EMSGSIZE; 210 } 211 212 static int crypto_report_ahash(struct sk_buff *skb, struct crypto_alg *alg) 213 { 214 struct crypto_stat rhash; 215 u64 v64; 216 u32 v32; 217 218 memset(&rhash, 0, sizeof(rhash)); 219 220 strncpy(rhash.type, "ahash", sizeof(rhash.type)); 221 222 v32 = atomic_read(&alg->hash_cnt); 223 rhash.stat_hash_cnt = v32; 224 v64 = atomic64_read(&alg->hash_tlen); 225 rhash.stat_hash_tlen = v64; 226 v32 = atomic_read(&alg->hash_err_cnt); 227 rhash.stat_hash_err_cnt = v32; 228 229 if (nla_put(skb, CRYPTOCFGA_STAT_HASH, 230 sizeof(struct crypto_stat), &rhash)) 231 goto nla_put_failure; 232 return 0; 233 234 nla_put_failure: 235 return -EMSGSIZE; 236 } 237 238 static int crypto_report_shash(struct sk_buff *skb, struct crypto_alg *alg) 239 { 240 struct crypto_stat rhash; 241 u64 v64; 242 u32 v32; 243 244 memset(&rhash, 0, sizeof(rhash)); 245 246 strncpy(rhash.type, "shash", sizeof(rhash.type)); 247 248 v32 = atomic_read(&alg->hash_cnt); 249 rhash.stat_hash_cnt = v32; 250 v64 = atomic64_read(&alg->hash_tlen); 251 rhash.stat_hash_tlen = v64; 252 v32 = atomic_read(&alg->hash_err_cnt); 253 rhash.stat_hash_err_cnt = v32; 254 255 if (nla_put(skb, CRYPTOCFGA_STAT_HASH, 256 sizeof(struct crypto_stat), &rhash)) 257 goto nla_put_failure; 258 return 0; 259 260 nla_put_failure: 261 return -EMSGSIZE; 262 } 263 264 static int crypto_report_rng(struct sk_buff *skb, struct crypto_alg *alg) 265 { 266 struct crypto_stat rrng; 267 u64 v64; 268 u32 v32; 269 270 memset(&rrng, 0, sizeof(rrng)); 271 272 strncpy(rrng.type, "rng", sizeof(rrng.type)); 273 274 v32 = atomic_read(&alg->generate_cnt); 275 rrng.stat_generate_cnt = v32; 276 v64 = atomic64_read(&alg->generate_tlen); 277 rrng.stat_generate_tlen = v64; 278 v32 = atomic_read(&alg->seed_cnt); 279 rrng.stat_seed_cnt = v32; 280 v32 = atomic_read(&alg->hash_err_cnt); 281 rrng.stat_rng_err_cnt = v32; 282 283 if (nla_put(skb, CRYPTOCFGA_STAT_RNG, 284 sizeof(struct crypto_stat), &rrng)) 285 goto nla_put_failure; 286 return 0; 287 288 nla_put_failure: 289 return -EMSGSIZE; 290 } 291 292 static int crypto_reportstat_one(struct crypto_alg *alg, 293 struct crypto_user_alg *ualg, 294 struct sk_buff *skb) 295 { 296 memset(ualg, 0, sizeof(*ualg)); 297 298 strlcpy(ualg->cru_name, alg->cra_name, sizeof(ualg->cru_name)); 299 strlcpy(ualg->cru_driver_name, alg->cra_driver_name, 300 sizeof(ualg->cru_driver_name)); 301 strlcpy(ualg->cru_module_name, module_name(alg->cra_module), 302 sizeof(ualg->cru_module_name)); 303 304 ualg->cru_type = 0; 305 ualg->cru_mask = 0; 306 ualg->cru_flags = alg->cra_flags; 307 ualg->cru_refcnt = refcount_read(&alg->cra_refcnt); 308 309 if (nla_put_u32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority)) 310 goto nla_put_failure; 311 if (alg->cra_flags & CRYPTO_ALG_LARVAL) { 312 struct crypto_stat rl; 313 314 memset(&rl, 0, sizeof(rl)); 315 strlcpy(rl.type, "larval", sizeof(rl.type)); 316 if (nla_put(skb, CRYPTOCFGA_STAT_LARVAL, 317 sizeof(struct crypto_stat), &rl)) 318 goto nla_put_failure; 319 goto out; 320 } 321 322 switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) { 323 case CRYPTO_ALG_TYPE_AEAD: 324 if (crypto_report_aead(skb, alg)) 325 goto nla_put_failure; 326 break; 327 case CRYPTO_ALG_TYPE_SKCIPHER: 328 if (crypto_report_cipher(skb, alg)) 329 goto nla_put_failure; 330 break; 331 case CRYPTO_ALG_TYPE_BLKCIPHER: 332 if (crypto_report_cipher(skb, alg)) 333 goto nla_put_failure; 334 break; 335 case CRYPTO_ALG_TYPE_CIPHER: 336 if (crypto_report_cipher(skb, alg)) 337 goto nla_put_failure; 338 break; 339 case CRYPTO_ALG_TYPE_COMPRESS: 340 if (crypto_report_comp(skb, alg)) 341 goto nla_put_failure; 342 break; 343 case CRYPTO_ALG_TYPE_ACOMPRESS: 344 if (crypto_report_acomp(skb, alg)) 345 goto nla_put_failure; 346 break; 347 case CRYPTO_ALG_TYPE_SCOMPRESS: 348 if (crypto_report_acomp(skb, alg)) 349 goto nla_put_failure; 350 break; 351 case CRYPTO_ALG_TYPE_AKCIPHER: 352 if (crypto_report_akcipher(skb, alg)) 353 goto nla_put_failure; 354 break; 355 case CRYPTO_ALG_TYPE_KPP: 356 if (crypto_report_kpp(skb, alg)) 357 goto nla_put_failure; 358 break; 359 case CRYPTO_ALG_TYPE_AHASH: 360 if (crypto_report_ahash(skb, alg)) 361 goto nla_put_failure; 362 break; 363 case CRYPTO_ALG_TYPE_HASH: 364 if (crypto_report_shash(skb, alg)) 365 goto nla_put_failure; 366 break; 367 case CRYPTO_ALG_TYPE_RNG: 368 if (crypto_report_rng(skb, alg)) 369 goto nla_put_failure; 370 break; 371 default: 372 pr_err("ERROR: Unhandled alg %d in %s\n", 373 alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL), 374 __func__); 375 } 376 377 out: 378 return 0; 379 380 nla_put_failure: 381 return -EMSGSIZE; 382 } 383 384 static int crypto_reportstat_alg(struct crypto_alg *alg, 385 struct crypto_dump_info *info) 386 { 387 struct sk_buff *in_skb = info->in_skb; 388 struct sk_buff *skb = info->out_skb; 389 struct nlmsghdr *nlh; 390 struct crypto_user_alg *ualg; 391 int err = 0; 392 393 nlh = nlmsg_put(skb, NETLINK_CB(in_skb).portid, info->nlmsg_seq, 394 CRYPTO_MSG_GETSTAT, sizeof(*ualg), info->nlmsg_flags); 395 if (!nlh) { 396 err = -EMSGSIZE; 397 goto out; 398 } 399 400 ualg = nlmsg_data(nlh); 401 402 err = crypto_reportstat_one(alg, ualg, skb); 403 if (err) { 404 nlmsg_cancel(skb, nlh); 405 goto out; 406 } 407 408 nlmsg_end(skb, nlh); 409 410 out: 411 return err; 412 } 413 414 int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, 415 struct nlattr **attrs) 416 { 417 struct crypto_user_alg *p = nlmsg_data(in_nlh); 418 struct crypto_alg *alg; 419 struct sk_buff *skb; 420 struct crypto_dump_info info; 421 int err; 422 423 if (!null_terminated(p->cru_name) || !null_terminated(p->cru_driver_name)) 424 return -EINVAL; 425 426 alg = crypto_alg_match(p, 0); 427 if (!alg) 428 return -ENOENT; 429 430 err = -ENOMEM; 431 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 432 if (!skb) 433 goto drop_alg; 434 435 info.in_skb = in_skb; 436 info.out_skb = skb; 437 info.nlmsg_seq = in_nlh->nlmsg_seq; 438 info.nlmsg_flags = 0; 439 440 err = crypto_reportstat_alg(alg, &info); 441 442 drop_alg: 443 crypto_mod_put(alg); 444 445 if (err) 446 return err; 447 448 return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).portid); 449 } 450 451 int crypto_dump_reportstat(struct sk_buff *skb, struct netlink_callback *cb) 452 { 453 struct crypto_alg *alg; 454 struct crypto_dump_info info; 455 int err; 456 457 if (cb->args[0]) 458 goto out; 459 460 cb->args[0] = 1; 461 462 info.in_skb = cb->skb; 463 info.out_skb = skb; 464 info.nlmsg_seq = cb->nlh->nlmsg_seq; 465 info.nlmsg_flags = NLM_F_MULTI; 466 467 list_for_each_entry(alg, &crypto_alg_list, cra_list) { 468 err = crypto_reportstat_alg(alg, &info); 469 if (err) 470 goto out_err; 471 } 472 473 out: 474 return skb->len; 475 out_err: 476 return err; 477 } 478 479 int crypto_dump_reportstat_done(struct netlink_callback *cb) 480 { 481 return 0; 482 } 483 484 MODULE_LICENSE("GPL"); 485