Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: xilinx - Register H/W key support with paes

Register gcm(paes) for hardware supported keys.

Signed-off-by: Harsh Jain <h.jain@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Harsh Jain and committed by
Herbert Xu
43f04786 0d120a39

+204 -100
+204 -100
drivers/crypto/xilinx/zynqmp-aes-gcm.c
··· 22 22 23 23 #define ZYNQMP_AES_KEY_SIZE AES_KEYSIZE_256 24 24 #define ZYNQMP_AES_AUTH_SIZE 16U 25 - #define ZYNQMP_KEY_SRC_SEL_KEY_LEN 1U 26 25 #define ZYNQMP_AES_BLK_SIZE 1U 27 26 #define ZYNQMP_AES_MIN_INPUT_BLK_SIZE 4U 28 27 #define ZYNQMP_AES_WORD_LEN 4U 29 28 30 - #define ZYNQMP_AES_GCM_TAG_MISMATCH_ERR 0x01 31 - #define ZYNQMP_AES_WRONG_KEY_SRC_ERR 0x13 32 - #define ZYNQMP_AES_PUF_NOT_PROGRAMMED 0xE300 29 + #define ZYNQMP_AES_GCM_TAG_MISMATCH_ERR 0x01 30 + #define ZYNQMP_AES_WRONG_KEY_SRC_ERR 0x13 31 + #define ZYNQMP_AES_PUF_NOT_PROGRAMMED 0xE300 32 + #define XILINX_KEY_MAGIC 0x3EA0 33 33 34 34 enum zynqmp_aead_op { 35 35 ZYNQMP_AES_DECRYPT = 0, ··· 42 42 ZYNQMP_AES_PUF_KEY 43 43 }; 44 44 45 - struct zynqmp_aead_drv_ctx { 46 - struct aead_engine_alg aead; 45 + struct xilinx_aead_dev { 47 46 struct device *dev; 48 47 struct crypto_engine *engine; 48 + struct xilinx_aead_alg *aead_algs; 49 49 }; 50 + 51 + struct xilinx_aead_alg { 52 + struct xilinx_aead_dev *aead_dev; 53 + struct aead_engine_alg aead; 54 + u8 dma_bit_mask; 55 + }; 56 + 57 + struct xilinx_hwkey_info { 58 + u16 magic; 59 + u16 type; 60 + } __packed; 50 61 51 62 struct zynqmp_aead_hw_req { 52 63 u64 src; ··· 75 64 u8 *iv; 76 65 u32 keylen; 77 66 u32 authsize; 78 - enum zynqmp_aead_keysrc keysrc; 67 + u8 keysrc; 79 68 struct crypto_aead *fbk_cipher; 80 69 }; 81 70 82 71 struct zynqmp_aead_req_ctx { 83 72 enum zynqmp_aead_op op; 84 73 }; 74 + 75 + static struct xilinx_aead_dev *aead_dev; 85 76 86 77 static int zynqmp_aes_aead_cipher(struct aead_request *req) 87 78 { ··· 188 175 static int zynqmp_fallback_check(struct zynqmp_aead_tfm_ctx *tfm_ctx, 189 176 struct aead_request *req) 190 177 { 191 - int need_fallback = 0; 192 178 struct zynqmp_aead_req_ctx *rq_ctx = aead_request_ctx(req); 193 179 194 180 if (tfm_ctx->authsize != ZYNQMP_AES_AUTH_SIZE && rq_ctx->op == ZYNQMP_AES_DECRYPT) 195 181 return 1; 196 182 197 - if (tfm_ctx->keysrc == ZYNQMP_AES_KUP_KEY && 198 - tfm_ctx->keylen != ZYNQMP_AES_KEY_SIZE) { 199 - need_fallback = 1; 200 - } 201 183 if (req->assoclen != 0 || 202 - req->cryptlen < ZYNQMP_AES_MIN_INPUT_BLK_SIZE) { 203 - need_fallback = 1; 204 - } 184 + req->cryptlen < ZYNQMP_AES_MIN_INPUT_BLK_SIZE) 185 + return 1; 186 + if (tfm_ctx->keylen == AES_KEYSIZE_128 || 187 + tfm_ctx->keylen == AES_KEYSIZE_192) 188 + return 1; 189 + 205 190 if ((req->cryptlen % ZYNQMP_AES_WORD_LEN) != 0) 206 - need_fallback = 1; 191 + return 1; 207 192 208 193 if (rq_ctx->op == ZYNQMP_AES_DECRYPT && 209 - req->cryptlen <= ZYNQMP_AES_AUTH_SIZE) { 210 - need_fallback = 1; 211 - } 212 - return need_fallback; 194 + req->cryptlen <= ZYNQMP_AES_AUTH_SIZE) 195 + return 1; 196 + 197 + return 0; 213 198 } 214 199 215 - static int zynqmp_handle_aes_req(struct crypto_engine *engine, 216 - void *req) 200 + static int zynqmp_handle_aes_req(struct crypto_engine *engine, void *req) 217 201 { 218 202 struct aead_request *areq = 219 203 container_of(req, struct aead_request, base); ··· 228 218 unsigned int keylen) 229 219 { 230 220 struct crypto_tfm *tfm = crypto_aead_tfm(aead); 231 - struct zynqmp_aead_tfm_ctx *tfm_ctx = 232 - (struct zynqmp_aead_tfm_ctx *)crypto_tfm_ctx(tfm); 233 - unsigned char keysrc; 221 + struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); 222 + int err; 234 223 235 - if (keylen == ZYNQMP_KEY_SRC_SEL_KEY_LEN) { 236 - keysrc = *key; 237 - if (keysrc == ZYNQMP_AES_KUP_KEY || 238 - keysrc == ZYNQMP_AES_DEV_KEY || 239 - keysrc == ZYNQMP_AES_PUF_KEY) { 240 - tfm_ctx->keysrc = (enum zynqmp_aead_keysrc)keysrc; 241 - } else { 242 - tfm_ctx->keylen = keylen; 243 - } 244 - } else { 245 - tfm_ctx->keylen = keylen; 246 - if (keylen == ZYNQMP_AES_KEY_SIZE) { 247 - tfm_ctx->keysrc = ZYNQMP_AES_KUP_KEY; 248 - memcpy(tfm_ctx->key, key, keylen); 249 - } 224 + if (keylen == ZYNQMP_AES_KEY_SIZE) { 225 + memcpy(tfm_ctx->key, key, keylen); 250 226 } 251 227 252 228 tfm_ctx->fbk_cipher->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK; 253 229 tfm_ctx->fbk_cipher->base.crt_flags |= (aead->base.crt_flags & 254 - CRYPTO_TFM_REQ_MASK); 230 + CRYPTO_TFM_REQ_MASK); 255 231 256 - return crypto_aead_setkey(tfm_ctx->fbk_cipher, key, keylen); 232 + err = crypto_aead_setkey(tfm_ctx->fbk_cipher, key, keylen); 233 + if (err) 234 + goto err; 235 + tfm_ctx->keylen = keylen; 236 + tfm_ctx->keysrc = ZYNQMP_AES_KUP_KEY; 237 + err: 238 + return err; 239 + } 240 + 241 + static int zynqmp_paes_aead_setkey(struct crypto_aead *aead, const u8 *key, 242 + unsigned int keylen) 243 + { 244 + struct crypto_tfm *tfm = crypto_aead_tfm(aead); 245 + struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); 246 + struct xilinx_hwkey_info hwkey; 247 + unsigned char keysrc; 248 + int err = -EINVAL; 249 + 250 + if (keylen != sizeof(struct xilinx_hwkey_info)) 251 + return -EINVAL; 252 + memcpy(&hwkey, key, sizeof(struct xilinx_hwkey_info)); 253 + if (hwkey.magic != XILINX_KEY_MAGIC) 254 + return -EINVAL; 255 + keysrc = hwkey.type; 256 + if (keysrc == ZYNQMP_AES_DEV_KEY || 257 + keysrc == ZYNQMP_AES_PUF_KEY) { 258 + tfm_ctx->keysrc = keysrc; 259 + tfm_ctx->keylen = sizeof(struct xilinx_hwkey_info); 260 + err = 0; 261 + } 262 + 263 + return err; 257 264 } 258 265 259 266 static int zynqmp_aes_aead_setauthsize(struct crypto_aead *aead, ··· 281 254 (struct zynqmp_aead_tfm_ctx *)crypto_tfm_ctx(tfm); 282 255 283 256 tfm_ctx->authsize = authsize; 284 - return crypto_aead_setauthsize(tfm_ctx->fbk_cipher, authsize); 257 + return tfm_ctx->fbk_cipher ? crypto_aead_setauthsize(tfm_ctx->fbk_cipher, authsize) : 0; 285 258 } 286 259 287 260 static int xilinx_aes_fallback_crypt(struct aead_request *req, bool encrypt) ··· 305 278 struct crypto_aead *aead = crypto_aead_reqtfm(req); 306 279 struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead); 307 280 struct aead_alg *alg = crypto_aead_alg(aead); 308 - struct zynqmp_aead_drv_ctx *drv_ctx; 281 + struct xilinx_aead_alg *drv_ctx; 309 282 int err; 310 283 284 + drv_ctx = container_of(alg, struct xilinx_aead_alg, aead.base); 285 + if (tfm_ctx->keysrc == ZYNQMP_AES_KUP_KEY && 286 + tfm_ctx->keylen == sizeof(struct xilinx_hwkey_info)) 287 + return -EINVAL; 288 + 311 289 rq_ctx->op = ZYNQMP_AES_ENCRYPT; 312 - drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, aead.base); 313 290 err = zynqmp_fallback_check(tfm_ctx, req); 314 291 if (err && tfm_ctx->keysrc != ZYNQMP_AES_KUP_KEY) 315 292 return -EOPNOTSUPP; ··· 321 290 if (err) 322 291 return xilinx_aes_fallback_crypt(req, true); 323 292 324 - return crypto_transfer_aead_request_to_engine(drv_ctx->engine, req); 293 + return crypto_transfer_aead_request_to_engine(drv_ctx->aead_dev->engine, req); 325 294 } 326 295 327 296 static int zynqmp_aes_aead_decrypt(struct aead_request *req) ··· 330 299 struct crypto_aead *aead = crypto_aead_reqtfm(req); 331 300 struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_aead_ctx(aead); 332 301 struct aead_alg *alg = crypto_aead_alg(aead); 333 - struct zynqmp_aead_drv_ctx *drv_ctx; 302 + struct xilinx_aead_alg *drv_ctx; 334 303 int err; 335 304 336 305 rq_ctx->op = ZYNQMP_AES_DECRYPT; 337 - drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, aead.base); 306 + drv_ctx = container_of(alg, struct xilinx_aead_alg, aead.base); 307 + if (tfm_ctx->keysrc == ZYNQMP_AES_KUP_KEY && 308 + tfm_ctx->keylen == sizeof(struct xilinx_hwkey_info)) 309 + return -EINVAL; 338 310 err = zynqmp_fallback_check(tfm_ctx, req); 339 311 if (err && tfm_ctx->keysrc != ZYNQMP_AES_KUP_KEY) 340 312 return -EOPNOTSUPP; 341 313 if (err) 342 314 return xilinx_aes_fallback_crypt(req, false); 343 315 344 - return crypto_transfer_aead_request_to_engine(drv_ctx->engine, req); 316 + return crypto_transfer_aead_request_to_engine(drv_ctx->aead_dev->engine, req); 317 + } 318 + 319 + static int xilinx_paes_aead_init(struct crypto_aead *aead) 320 + { 321 + struct crypto_tfm *tfm = crypto_aead_tfm(aead); 322 + struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); 323 + struct xilinx_aead_alg *drv_alg; 324 + struct aead_alg *alg = crypto_aead_alg(aead); 325 + 326 + drv_alg = container_of(alg, struct xilinx_aead_alg, aead.base); 327 + tfm_ctx->dev = drv_alg->aead_dev->dev; 328 + tfm_ctx->keylen = 0; 329 + 330 + tfm_ctx->fbk_cipher = NULL; 331 + crypto_aead_set_reqsize(aead, sizeof(struct zynqmp_aead_req_ctx)); 332 + 333 + return 0; 345 334 } 346 335 347 336 static int zynqmp_aes_aead_init(struct crypto_aead *aead) ··· 369 318 struct crypto_tfm *tfm = crypto_aead_tfm(aead); 370 319 struct zynqmp_aead_tfm_ctx *tfm_ctx = 371 320 (struct zynqmp_aead_tfm_ctx *)crypto_tfm_ctx(tfm); 372 - struct zynqmp_aead_drv_ctx *drv_ctx; 321 + struct xilinx_aead_alg *drv_ctx; 373 322 struct aead_alg *alg = crypto_aead_alg(aead); 374 323 375 - drv_ctx = container_of(alg, struct zynqmp_aead_drv_ctx, aead.base); 376 - tfm_ctx->dev = drv_ctx->dev; 324 + drv_ctx = container_of(alg, struct xilinx_aead_alg, aead.base); 325 + tfm_ctx->dev = drv_ctx->aead_dev->dev; 326 + tfm_ctx->keylen = 0; 377 327 378 328 tfm_ctx->fbk_cipher = crypto_alloc_aead(drv_ctx->aead.base.base.cra_name, 379 329 0, ··· 393 341 return 0; 394 342 } 395 343 344 + static void xilinx_paes_aead_exit(struct crypto_aead *aead) 345 + { 346 + struct crypto_tfm *tfm = crypto_aead_tfm(aead); 347 + struct zynqmp_aead_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); 348 + 349 + memzero_explicit(tfm_ctx, sizeof(struct zynqmp_aead_tfm_ctx)); 350 + } 351 + 396 352 static void zynqmp_aes_aead_exit(struct crypto_aead *aead) 397 353 { 398 354 struct crypto_tfm *tfm = crypto_aead_tfm(aead); ··· 414 354 memzero_explicit(tfm_ctx, sizeof(struct zynqmp_aead_tfm_ctx)); 415 355 } 416 356 417 - static struct zynqmp_aead_drv_ctx zynqmp_aes_drv_ctx = { 418 - .aead.base = { 419 - .setkey = zynqmp_aes_aead_setkey, 420 - .setauthsize = zynqmp_aes_aead_setauthsize, 421 - .encrypt = zynqmp_aes_aead_encrypt, 422 - .decrypt = zynqmp_aes_aead_decrypt, 423 - .init = zynqmp_aes_aead_init, 424 - .exit = zynqmp_aes_aead_exit, 425 - .ivsize = GCM_AES_IV_SIZE, 426 - .maxauthsize = ZYNQMP_AES_AUTH_SIZE, 427 - .base = { 428 - .cra_name = "gcm(aes)", 429 - .cra_driver_name = "xilinx-zynqmp-aes-gcm", 430 - .cra_priority = 200, 431 - .cra_flags = CRYPTO_ALG_TYPE_AEAD | 432 - CRYPTO_ALG_ASYNC | 433 - CRYPTO_ALG_ALLOCATES_MEMORY | 434 - CRYPTO_ALG_KERN_DRIVER_ONLY | 435 - CRYPTO_ALG_NEED_FALLBACK, 436 - .cra_blocksize = ZYNQMP_AES_BLK_SIZE, 437 - .cra_ctxsize = sizeof(struct zynqmp_aead_tfm_ctx), 438 - .cra_module = THIS_MODULE, 439 - } 357 + static struct xilinx_aead_alg zynqmp_aes_algs[] = { 358 + { 359 + .aead.base = { 360 + .setkey = zynqmp_aes_aead_setkey, 361 + .setauthsize = zynqmp_aes_aead_setauthsize, 362 + .encrypt = zynqmp_aes_aead_encrypt, 363 + .decrypt = zynqmp_aes_aead_decrypt, 364 + .init = zynqmp_aes_aead_init, 365 + .exit = zynqmp_aes_aead_exit, 366 + .ivsize = GCM_AES_IV_SIZE, 367 + .maxauthsize = ZYNQMP_AES_AUTH_SIZE, 368 + .base = { 369 + .cra_name = "gcm(aes)", 370 + .cra_driver_name = "xilinx-zynqmp-aes-gcm", 371 + .cra_priority = 200, 372 + .cra_flags = CRYPTO_ALG_TYPE_AEAD | 373 + CRYPTO_ALG_ASYNC | 374 + CRYPTO_ALG_ALLOCATES_MEMORY | 375 + CRYPTO_ALG_KERN_DRIVER_ONLY | 376 + CRYPTO_ALG_NEED_FALLBACK, 377 + .cra_blocksize = ZYNQMP_AES_BLK_SIZE, 378 + .cra_ctxsize = sizeof(struct zynqmp_aead_tfm_ctx), 379 + .cra_module = THIS_MODULE, 380 + } 381 + }, 382 + .aead.op = { 383 + .do_one_request = zynqmp_handle_aes_req, 384 + }, 385 + .dma_bit_mask = ZYNQMP_DMA_BIT_MASK, 440 386 }, 441 - .aead.op = { 442 - .do_one_request = zynqmp_handle_aes_req, 387 + { 388 + .aead.base = { 389 + .setkey = zynqmp_paes_aead_setkey, 390 + .setauthsize = zynqmp_aes_aead_setauthsize, 391 + .encrypt = zynqmp_aes_aead_encrypt, 392 + .decrypt = zynqmp_aes_aead_decrypt, 393 + .init = xilinx_paes_aead_init, 394 + .exit = xilinx_paes_aead_exit, 395 + .ivsize = GCM_AES_IV_SIZE, 396 + .maxauthsize = ZYNQMP_AES_AUTH_SIZE, 397 + .base = { 398 + .cra_name = "gcm(paes)", 399 + .cra_driver_name = "xilinx-zynqmp-paes-gcm", 400 + .cra_priority = 200, 401 + .cra_flags = CRYPTO_ALG_TYPE_AEAD | 402 + CRYPTO_ALG_ASYNC | 403 + CRYPTO_ALG_ALLOCATES_MEMORY | 404 + CRYPTO_ALG_KERN_DRIVER_ONLY, 405 + .cra_blocksize = ZYNQMP_AES_BLK_SIZE, 406 + .cra_ctxsize = sizeof(struct zynqmp_aead_tfm_ctx), 407 + .cra_module = THIS_MODULE, 408 + } 409 + }, 410 + .aead.op = { 411 + .do_one_request = zynqmp_handle_aes_req, 412 + }, 413 + .dma_bit_mask = ZYNQMP_DMA_BIT_MASK, 443 414 }, 415 + { /* sentinel */ } 444 416 }; 445 417 446 418 static struct xlnx_feature aes_feature_map[] = { 447 419 { 448 420 .family = PM_ZYNQMP_FAMILY_CODE, 449 421 .feature_id = PM_SECURE_AES, 450 - .data = &zynqmp_aes_drv_ctx, 422 + .data = zynqmp_aes_algs, 451 423 }, 452 424 { /* sentinel */ } 453 425 }; 454 426 455 427 static int zynqmp_aes_aead_probe(struct platform_device *pdev) 456 428 { 457 - struct zynqmp_aead_drv_ctx *aes_drv_ctx; 429 + struct xilinx_aead_alg *aead_algs; 458 430 struct device *dev = &pdev->dev; 459 431 int err; 432 + int i; 460 433 461 434 /* Verify the hardware is present */ 462 - aes_drv_ctx = xlnx_get_crypto_dev_data(aes_feature_map); 463 - if (IS_ERR(aes_drv_ctx)) { 435 + aead_algs = xlnx_get_crypto_dev_data(aes_feature_map); 436 + if (IS_ERR(aead_algs)) { 464 437 dev_err(dev, "AES is not supported on the platform\n"); 465 - return PTR_ERR(aes_drv_ctx); 438 + return PTR_ERR(aead_algs); 466 439 } 467 440 468 441 /* ZynqMP AES driver supports only one instance */ 469 - if (!aes_drv_ctx->dev) 470 - aes_drv_ctx->dev = dev; 471 - else 442 + if (aead_dev) 472 443 return -ENODEV; 473 444 474 - platform_set_drvdata(pdev, aes_drv_ctx); 475 - err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(ZYNQMP_DMA_BIT_MASK)); 445 + aead_dev = devm_kzalloc(dev, sizeof(*aead_dev), GFP_KERNEL); 446 + if (!aead_dev) 447 + return -ENOMEM; 448 + aead_dev->dev = dev; 449 + aead_dev->aead_algs = aead_algs; 450 + platform_set_drvdata(pdev, aead_dev); 451 + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(aead_algs[0].dma_bit_mask)); 476 452 if (err < 0) { 477 453 dev_err(dev, "No usable DMA configuration\n"); 478 454 return err; 479 455 } 480 456 481 - aes_drv_ctx->engine = crypto_engine_alloc_init(dev, 1); 482 - if (!aes_drv_ctx->engine) { 457 + aead_dev->engine = crypto_engine_alloc_init(dev, 1); 458 + if (!aead_dev->engine) { 483 459 dev_err(dev, "Cannot alloc AES engine\n"); 484 460 err = -ENOMEM; 485 461 goto err_engine; 486 462 } 487 463 488 - err = crypto_engine_start(aes_drv_ctx->engine); 464 + err = crypto_engine_start(aead_dev->engine); 489 465 if (err) { 490 466 dev_err(dev, "Cannot start AES engine\n"); 491 467 goto err_engine; 492 468 } 493 469 494 - err = crypto_engine_register_aead(&aes_drv_ctx->aead); 495 - if (err < 0) { 496 - dev_err(dev, "Failed to register AEAD alg.\n"); 497 - goto err_engine; 470 + for (i = 0; aead_dev->aead_algs[i].dma_bit_mask; i++) { 471 + aead_dev->aead_algs[i].aead_dev = aead_dev; 472 + err = crypto_engine_register_aead(&aead_dev->aead_algs[i].aead); 473 + if (err < 0) { 474 + dev_err(dev, "Failed to register AEAD alg %d.\n", i); 475 + goto err_alg_register; 476 + } 498 477 } 499 478 return 0; 500 479 480 + return 0; 481 + 482 + err_alg_register: 483 + while (i > 0) 484 + crypto_engine_unregister_aead(&aead_dev->aead_algs[--i].aead); 501 485 err_engine: 502 - if (aes_drv_ctx->engine) 503 - crypto_engine_exit(aes_drv_ctx->engine); 486 + crypto_engine_exit(aead_dev->engine); 504 487 505 488 return err; 506 489 } 507 490 508 491 static void zynqmp_aes_aead_remove(struct platform_device *pdev) 509 492 { 510 - struct zynqmp_aead_drv_ctx *aes_drv_ctx; 493 + aead_dev = platform_get_drvdata(pdev); 494 + crypto_engine_exit(aead_dev->engine); 495 + for (int i = 0; aead_dev->aead_algs[i].dma_bit_mask; i++) 496 + crypto_engine_unregister_aead(&aead_dev->aead_algs[i].aead); 511 497 512 - aes_drv_ctx = platform_get_drvdata(pdev); 513 - crypto_engine_exit(aes_drv_ctx->engine); 514 - crypto_engine_unregister_aead(&aes_drv_ctx->aead); 498 + aead_dev = NULL; 515 499 } 516 500 517 501 static struct platform_driver zynqmp_aes_driver = {