Commit 0475add3c27a43a6599fe6338f8fffe919a13547

Authored by Brilly Wu
Committed by Herbert Xu
1 parent 7dfc2179ec

crypto: padlock - Add SHA-1/256 module for VIA Nano

Add new SHA-1/256 module that never needs any fallback and just calls the
PadLock hardware instruction supported from VIA Nano processors to implement
the "update" and "final" function.

They are respectively named "sha1_alg_nano" and "sha256_alg_nano", and will
be used on any VIA Nano processor or the later ones. On VIA C7 CPU, the
"sha1_alg" and "sha256_alg" modules will still be used as before.

Signed-off-by: Brilly Wu <brillywu@viatech.com.cn>
Signed-off-by: Kary Jin <karyjin@viatech.com.cn>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 1 changed file with 264 additions and 5 deletions Side-by-side Diff

drivers/crypto/padlock-sha.c
... ... @@ -288,9 +288,250 @@
288 288 }
289 289 };
290 290  
  291 +/* Add two shash_alg instance for hardware-implemented *
  292 +* multiple-parts hash supported by VIA Nano Processor.*/
  293 +static int padlock_sha1_init_nano(struct shash_desc *desc)
  294 +{
  295 + struct sha1_state *sctx = shash_desc_ctx(desc);
  296 +
  297 + *sctx = (struct sha1_state){
  298 + .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
  299 + };
  300 +
  301 + return 0;
  302 +}
  303 +
  304 +static int padlock_sha1_update_nano(struct shash_desc *desc,
  305 + const u8 *data, unsigned int len)
  306 +{
  307 + struct sha1_state *sctx = shash_desc_ctx(desc);
  308 + unsigned int partial, done;
  309 + const u8 *src;
  310 + /*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/
  311 + u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
  312 + ((aligned(STACK_ALIGN)));
  313 + u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
  314 + int ts_state;
  315 +
  316 + partial = sctx->count & 0x3f;
  317 + sctx->count += len;
  318 + done = 0;
  319 + src = data;
  320 + memcpy(dst, (u8 *)(sctx->state), SHA1_DIGEST_SIZE);
  321 +
  322 + if ((partial + len) >= SHA1_BLOCK_SIZE) {
  323 +
  324 + /* Append the bytes in state's buffer to a block to handle */
  325 + if (partial) {
  326 + done = -partial;
  327 + memcpy(sctx->buffer + partial, data,
  328 + done + SHA1_BLOCK_SIZE);
  329 + src = sctx->buffer;
  330 + ts_state = irq_ts_save();
  331 + asm volatile (".byte 0xf3,0x0f,0xa6,0xc8"
  332 + : "+S"(src), "+D"(dst) \
  333 + : "a"((long)-1), "c"((unsigned long)1));
  334 + irq_ts_restore(ts_state);
  335 + done += SHA1_BLOCK_SIZE;
  336 + src = data + done;
  337 + }
  338 +
  339 + /* Process the left bytes from the input data */
  340 + if (len - done >= SHA1_BLOCK_SIZE) {
  341 + ts_state = irq_ts_save();
  342 + asm volatile (".byte 0xf3,0x0f,0xa6,0xc8"
  343 + : "+S"(src), "+D"(dst)
  344 + : "a"((long)-1),
  345 + "c"((unsigned long)((len - done) / SHA1_BLOCK_SIZE)));
  346 + irq_ts_restore(ts_state);
  347 + done += ((len - done) - (len - done) % SHA1_BLOCK_SIZE);
  348 + src = data + done;
  349 + }
  350 + partial = 0;
  351 + }
  352 + memcpy((u8 *)(sctx->state), dst, SHA1_DIGEST_SIZE);
  353 + memcpy(sctx->buffer + partial, src, len - done);
  354 +
  355 + return 0;
  356 +}
  357 +
  358 +static int padlock_sha1_final_nano(struct shash_desc *desc, u8 *out)
  359 +{
  360 + struct sha1_state *state = (struct sha1_state *)shash_desc_ctx(desc);
  361 + unsigned int partial, padlen;
  362 + __be64 bits;
  363 + static const u8 padding[64] = { 0x80, };
  364 +
  365 + bits = cpu_to_be64(state->count << 3);
  366 +
  367 + /* Pad out to 56 mod 64 */
  368 + partial = state->count & 0x3f;
  369 + padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial);
  370 + padlock_sha1_update_nano(desc, padding, padlen);
  371 +
  372 + /* Append length field bytes */
  373 + padlock_sha1_update_nano(desc, (const u8 *)&bits, sizeof(bits));
  374 +
  375 + /* Swap to output */
  376 + padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 5);
  377 +
  378 + return 0;
  379 +}
  380 +
  381 +static int padlock_sha256_init_nano(struct shash_desc *desc)
  382 +{
  383 + struct sha256_state *sctx = shash_desc_ctx(desc);
  384 +
  385 + *sctx = (struct sha256_state){
  386 + .state = { SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3, \
  387 + SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7},
  388 + };
  389 +
  390 + return 0;
  391 +}
  392 +
  393 +static int padlock_sha256_update_nano(struct shash_desc *desc, const u8 *data,
  394 + unsigned int len)
  395 +{
  396 + struct sha256_state *sctx = shash_desc_ctx(desc);
  397 + unsigned int partial, done;
  398 + const u8 *src;
  399 + /*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/
  400 + u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
  401 + ((aligned(STACK_ALIGN)));
  402 + u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
  403 + int ts_state;
  404 +
  405 + partial = sctx->count & 0x3f;
  406 + sctx->count += len;
  407 + done = 0;
  408 + src = data;
  409 + memcpy(dst, (u8 *)(sctx->state), SHA256_DIGEST_SIZE);
  410 +
  411 + if ((partial + len) >= SHA256_BLOCK_SIZE) {
  412 +
  413 + /* Append the bytes in state's buffer to a block to handle */
  414 + if (partial) {
  415 + done = -partial;
  416 + memcpy(sctx->buf + partial, data,
  417 + done + SHA256_BLOCK_SIZE);
  418 + src = sctx->buf;
  419 + ts_state = irq_ts_save();
  420 + asm volatile (".byte 0xf3,0x0f,0xa6,0xd0"
  421 + : "+S"(src), "+D"(dst)
  422 + : "a"((long)-1), "c"((unsigned long)1));
  423 + irq_ts_restore(ts_state);
  424 + done += SHA256_BLOCK_SIZE;
  425 + src = data + done;
  426 + }
  427 +
  428 + /* Process the left bytes from input data*/
  429 + if (len - done >= SHA256_BLOCK_SIZE) {
  430 + ts_state = irq_ts_save();
  431 + asm volatile (".byte 0xf3,0x0f,0xa6,0xd0"
  432 + : "+S"(src), "+D"(dst)
  433 + : "a"((long)-1),
  434 + "c"((unsigned long)((len - done) / 64)));
  435 + irq_ts_restore(ts_state);
  436 + done += ((len - done) - (len - done) % 64);
  437 + src = data + done;
  438 + }
  439 + partial = 0;
  440 + }
  441 + memcpy((u8 *)(sctx->state), dst, SHA256_DIGEST_SIZE);
  442 + memcpy(sctx->buf + partial, src, len - done);
  443 +
  444 + return 0;
  445 +}
  446 +
  447 +static int padlock_sha256_final_nano(struct shash_desc *desc, u8 *out)
  448 +{
  449 + struct sha256_state *state =
  450 + (struct sha256_state *)shash_desc_ctx(desc);
  451 + unsigned int partial, padlen;
  452 + __be64 bits;
  453 + static const u8 padding[64] = { 0x80, };
  454 +
  455 + bits = cpu_to_be64(state->count << 3);
  456 +
  457 + /* Pad out to 56 mod 64 */
  458 + partial = state->count & 0x3f;
  459 + padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial);
  460 + padlock_sha256_update_nano(desc, padding, padlen);
  461 +
  462 + /* Append length field bytes */
  463 + padlock_sha256_update_nano(desc, (const u8 *)&bits, sizeof(bits));
  464 +
  465 + /* Swap to output */
  466 + padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 8);
  467 +
  468 + return 0;
  469 +}
  470 +
  471 +static int padlock_sha_export_nano(struct shash_desc *desc,
  472 + void *out)
  473 +{
  474 + int statesize = crypto_shash_statesize(desc->tfm);
  475 + void *sctx = shash_desc_ctx(desc);
  476 +
  477 + memcpy(out, sctx, statesize);
  478 + return 0;
  479 +}
  480 +
  481 +static int padlock_sha_import_nano(struct shash_desc *desc,
  482 + const void *in)
  483 +{
  484 + int statesize = crypto_shash_statesize(desc->tfm);
  485 + void *sctx = shash_desc_ctx(desc);
  486 +
  487 + memcpy(sctx, in, statesize);
  488 + return 0;
  489 +}
  490 +
  491 +static struct shash_alg sha1_alg_nano = {
  492 + .digestsize = SHA1_DIGEST_SIZE,
  493 + .init = padlock_sha1_init_nano,
  494 + .update = padlock_sha1_update_nano,
  495 + .final = padlock_sha1_final_nano,
  496 + .export = padlock_sha_export_nano,
  497 + .import = padlock_sha_import_nano,
  498 + .descsize = sizeof(struct sha1_state),
  499 + .statesize = sizeof(struct sha1_state),
  500 + .base = {
  501 + .cra_name = "sha1",
  502 + .cra_driver_name = "sha1-padlock-nano",
  503 + .cra_priority = PADLOCK_CRA_PRIORITY,
  504 + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  505 + .cra_blocksize = SHA1_BLOCK_SIZE,
  506 + .cra_module = THIS_MODULE,
  507 + }
  508 +};
  509 +
  510 +static struct shash_alg sha256_alg_nano = {
  511 + .digestsize = SHA256_DIGEST_SIZE,
  512 + .init = padlock_sha256_init_nano,
  513 + .update = padlock_sha256_update_nano,
  514 + .final = padlock_sha256_final_nano,
  515 + .export = padlock_sha_export_nano,
  516 + .import = padlock_sha_import_nano,
  517 + .descsize = sizeof(struct sha256_state),
  518 + .statesize = sizeof(struct sha256_state),
  519 + .base = {
  520 + .cra_name = "sha256",
  521 + .cra_driver_name = "sha256-padlock-nano",
  522 + .cra_priority = PADLOCK_CRA_PRIORITY,
  523 + .cra_flags = CRYPTO_ALG_TYPE_SHASH,
  524 + .cra_blocksize = SHA256_BLOCK_SIZE,
  525 + .cra_module = THIS_MODULE,
  526 + }
  527 +};
  528 +
291 529 static int __init padlock_init(void)
292 530 {
293 531 int rc = -ENODEV;
  532 + struct cpuinfo_x86 *c = &cpu_data(0);
  533 + struct shash_alg *sha1;
  534 + struct shash_alg *sha256;
294 535  
295 536 if (!cpu_has_phe) {
296 537 printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n");
297 538  
... ... @@ -302,11 +543,21 @@
302 543 return -ENODEV;
303 544 }
304 545  
305   - rc = crypto_register_shash(&sha1_alg);
  546 + /* Register the newly added algorithm module if on *
  547 + * VIA Nano processor, or else just do as before */
  548 + if (c->x86_model < 0x0f) {
  549 + sha1 = &sha1_alg;
  550 + sha256 = &sha256_alg;
  551 + } else {
  552 + sha1 = &sha1_alg_nano;
  553 + sha256 = &sha256_alg_nano;
  554 + }
  555 +
  556 + rc = crypto_register_shash(sha1);
306 557 if (rc)
307 558 goto out;
308 559  
309   - rc = crypto_register_shash(&sha256_alg);
  560 + rc = crypto_register_shash(sha256);
310 561 if (rc)
311 562 goto out_unreg1;
312 563  
... ... @@ -315,7 +566,8 @@
315 566 return 0;
316 567  
317 568 out_unreg1:
318   - crypto_unregister_shash(&sha1_alg);
  569 + crypto_unregister_shash(sha1);
  570 +
319 571 out:
320 572 printk(KERN_ERR PFX "VIA PadLock SHA1/SHA256 initialization failed.\n");
321 573 return rc;
... ... @@ -323,8 +575,15 @@
323 575  
324 576 static void __exit padlock_fini(void)
325 577 {
326   - crypto_unregister_shash(&sha1_alg);
327   - crypto_unregister_shash(&sha256_alg);
  578 + struct cpuinfo_x86 *c = &cpu_data(0);
  579 +
  580 + if (c->x86_model >= 0x0f) {
  581 + crypto_unregister_shash(&sha1_alg_nano);
  582 + crypto_unregister_shash(&sha256_alg_nano);
  583 + } else {
  584 + crypto_unregister_shash(&sha1_alg);
  585 + crypto_unregister_shash(&sha256_alg);
  586 + }
328 587 }
329 588  
330 589 module_init(padlock_init);