linux-stable/crypto
Ignat Korchagin f145d411a6 crypto: rsa - implement Chinese Remainder Theorem for faster private key operations
Changes from v1:
  * exported mpi_sub and mpi_mul, otherwise the build fails when RSA is a module

The kernel RSA ASN.1 private key parser already supports only private keys with
additional values to be used with the Chinese Remainder Theorem [1], but these
values are currently not used.

This rudimentary CRT implementation speeds up RSA private key operations for the
following Go benchmark up to ~3x.

This implementation also tries to minimise the allocation of additional MPIs,
so existing MPIs are reused as much as possible (hence the variable names are a
bit weird).

The benchmark used:

```
package keyring_test

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"io"
	"syscall"
	"testing"
	"unsafe"
)

type KeySerial int32
type Keyring int32

const (
	KEY_SPEC_PROCESS_KEYRING Keyring = -2
	KEYCTL_PKEY_SIGN                 = 27
)

var (
	keyTypeAsym = []byte("asymmetric\x00")
	sha256pkcs1 = []byte("enc=pkcs1 hash=sha256\x00")
)

func (keyring Keyring) LoadAsym(desc string, payload []byte) (KeySerial, error) {
	cdesc := []byte(desc + "\x00")
	serial, _, errno := syscall.Syscall6(syscall.SYS_ADD_KEY, uintptr(unsafe.Pointer(&keyTypeAsym[0])), uintptr(unsafe.Pointer(&cdesc[0])), uintptr(unsafe.Pointer(&payload[0])), uintptr(len(payload)), uintptr(keyring), uintptr(0))
	if errno == 0 {
		return KeySerial(serial), nil
	}

	return KeySerial(serial), errno
}

type pkeyParams struct {
	key_id         KeySerial
	in_len         uint32
	out_or_in2_len uint32
	__spare        [7]uint32
}

// the output signature buffer is an input parameter here, because we want to
// avoid Go buffer allocation leaking into our benchmarks
func (key KeySerial) Sign(info, digest, out []byte) error {
	var params pkeyParams
	params.key_id = key
	params.in_len = uint32(len(digest))
	params.out_or_in2_len = uint32(len(out))

	_, _, errno := syscall.Syscall6(syscall.SYS_KEYCTL, KEYCTL_PKEY_SIGN, uintptr(unsafe.Pointer(&params)), uintptr(unsafe.Pointer(&info[0])), uintptr(unsafe.Pointer(&digest[0])), uintptr(unsafe.Pointer(&out[0])), uintptr(0))
	if errno == 0 {
		return nil
	}

	return errno
}

func BenchmarkSign(b *testing.B) {
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		b.Fatalf("failed to generate private key: %v", err)
	}

	pkcs8, err := x509.MarshalPKCS8PrivateKey(priv)
	if err != nil {
		b.Fatalf("failed to serialize the private key to PKCS8 blob: %v", err)
	}

	serial, err := KEY_SPEC_PROCESS_KEYRING.LoadAsym("test rsa key", pkcs8)
	if err != nil {
		b.Fatalf("failed to load the private key into the keyring: %v", err)
	}

	b.Logf("loaded test rsa key: %v", serial)

	digest := make([]byte, 32)
	_, err = io.ReadFull(rand.Reader, digest)
	if err != nil {
		b.Fatalf("failed to generate a random digest: %v", err)
	}

	sig := make([]byte, 256)
	for n := 0; n < b.N; n++ {
		err = serial.Sign(sha256pkcs1, digest, sig)
		if err != nil {
			b.Fatalf("failed to sign the digest: %v", err)
		}
	}

	err = rsa.VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, digest, sig)
	if err != nil {
		b.Fatalf("failed to verify the signature: %v", err)
	}
}
```

[1]: https://en.wikipedia.org/wiki/RSA_(cryptosystem)#Using_the_Chinese_remainder_algorithm

Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2022-06-24 17:12:29 +08:00
..
asymmetric_keys certs: Factor out the blacklist hash creation 2022-05-23 18:47:49 +03:00
async_tx crypto: cleanup comments 2022-03-03 10:49:20 +12:00
842.c
acompress.c
adiantum.c
aead.c
aegis128-core.c
aegis128-neon-inner.c
aegis128-neon.c
aegis.h
aes_generic.c
aes_ti.c
af_alg.c crypto: af_alg - get rid of alg_memory_allocated 2022-02-15 14:29:04 +00:00
ahash.c
akcipher.c
algapi.c Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2022-03-21 16:02:36 -07:00
algboss.c exit: Rename module_put_and_exit to module_put_and_kthread_exit 2021-12-13 12:04:45 -06:00
algif_aead.c
algif_hash.c
algif_rng.c
algif_skcipher.c
ansi_cprng.c
anubis.c
api.c Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2022-03-21 16:02:36 -07:00
arc4.c
authenc.c crypto: authenc - Fix sleep in atomic context in decrypt_tail 2022-01-31 11:21:44 +11:00
authencesn.c
blake2b_generic.c
blowfish_common.c
blowfish_generic.c
camellia_generic.c
cast5_generic.c
cast6_generic.c
cast_common.c
cbc.c
ccm.c
cfb.c crypto: cleanup comments 2022-03-03 10:49:20 +12:00
chacha20poly1305.c
chacha_generic.c
cipher.c
cmac.c
compress.c
crc32_generic.c
crc32c_generic.c
crc64_rocksoft_generic.c crypto: add rocksoft 64b crc guard tag framework 2022-03-07 12:48:35 -07:00
crct10dif_common.c
crct10dif_generic.c
cryptd.c crypto: cryptd - Protect per-CPU resource by disabling BH. 2022-05-13 17:24:48 +08:00
crypto_engine.c crypto: engine - Add parameter description in crypto_transfer_request() kernel-doc comment 2022-04-08 16:13:30 +08:00
crypto_null.c
crypto_user_base.c
crypto_user_stat.c
ctr.c
cts.c
curve25519-generic.c
deflate.c
des_generic.c
dh_helper.c crypto: dh - split out deserialization code from crypto_dh_decode() 2022-03-03 10:47:50 +12:00
dh.c crypto: dh - Remove the unused function dh_safe_prime_dh_alg() 2022-03-14 14:45:45 +12:00
drbg.c crypto: drbg - ignore jitterentropy errors if not in FIPS mode 2021-12-11 16:48:06 +11:00
ecb.c
ecc_curve_defs.h
ecc.c crypto: ecc - Export additional helper functions 2021-10-29 21:04:03 +08:00
ecdh_helper.c
ecdh.c crypto: ecc - Move ecc.h to include/crypto/internal 2021-10-29 21:04:03 +08:00
ecdsa.c crypto: ecc - Move ecc.h to include/crypto/internal 2021-10-29 21:04:03 +08:00
ecdsasignature.asn1
echainiv.c
ecrdsa_defs.h crypto: ecc - Move ecc.h to include/crypto/internal 2021-10-29 21:04:03 +08:00
ecrdsa_params.asn1
ecrdsa_pub_key.asn1
ecrdsa.c crypto: ecrdsa - Fix incorrect use of vli_cmp 2022-04-29 13:44:58 +08:00
essiv.c
fcrypt.c
fips.c
gcm.c
geniv.c
gf128mul.c
ghash-generic.c
hash_info.c
hctr2.c crypto: hctr2 - Add HCTR2 support 2022-06-10 16:40:17 +08:00
hmac.c crypto: hmac - disallow keys < 112 bits in FIPS mode 2022-02-11 20:22:01 +11:00
internal.h crypto: api - Fix built-in testing dependency failures 2021-09-24 16:03:05 +08:00
jitterentropy-kcapi.c crypto: jitter - don't limit ->health_failure check to FIPS mode 2021-12-11 16:48:06 +11:00
jitterentropy.c crypto: jitter - add oversampling of noise source 2021-12-31 18:10:54 +11:00
jitterentropy.h crypto: jitter - don't limit ->health_failure check to FIPS mode 2021-12-11 16:48:06 +11:00
Kconfig crypto: blake2s - remove shash module 2022-06-10 16:43:49 +08:00
kdf_sp800108.c crypto: kdf - add SP800-108 counter key derivation function 2021-11-26 16:25:17 +11:00
keywrap.c
khazad.c crypto: khazad,wp512 - remove leading spaces before tabs 2021-05-28 15:11:44 +08:00
kpp.c crypto: kpp - provide support for KPP spawns 2022-03-03 10:47:50 +12:00
lrw.c crypto: lrw - Add dependency on ecb 2022-02-18 16:21:08 +11:00
lz4.c
lz4hc.c
lzo-rle.c
lzo.c
Makefile crypto: blake2s - remove shash module 2022-06-10 16:43:49 +08:00
md4.c
md5.c
michael_mic.c
nhpoly1305.c
ofb.c
pcbc.c
pcrypt.c crypto: pcrypt - Delay write to padata->info 2021-10-29 21:04:04 +08:00
poly1305_generic.c
polyval-generic.c crypto: x86/polyval - Add PCLMULQDQ accelerated implementation of POLYVAL 2022-06-10 16:40:17 +08:00
proc.c
ripemd.h
rmd160.c
rng.c
rsa_helper.c
rsa-pkcs1pad.c crypto: rsa-pkcs1pad - use clearer variable names 2022-01-31 11:21:44 +11:00
rsa.c crypto: rsa - implement Chinese Remainder Theorem for faster private key operations 2022-06-24 17:12:29 +08:00
rsaprivkey.asn1
rsapubkey.asn1
scatterwalk.c
scompress.c
seed.c
seqiv.c
serpent_generic.c
sha1_generic.c
sha3_generic.c
sha256_generic.c crypto: sha256 - remove duplicate generic hash init function 2021-12-31 18:10:54 +11:00
sha512_generic.c crypto: sha512 - remove imaginary and mystifying clearing of variables 2021-08-27 16:30:19 +08:00
shash.c crypto: shash - avoid comparing pointers to exported functions under CFI 2021-06-17 15:07:31 +08:00
simd.c
skcipher.c crypto: skcipher - in_irq() cleanup 2021-08-21 15:44:58 +08:00
sm2.c crypto: cleanup comments 2022-03-03 10:49:20 +12:00
sm2signature.asn1
sm3_generic.c crypto: sm3 - make dependent on sm3 library 2022-01-28 16:51:11 +11:00
sm3.c crypto: sm3,sm4 - move into crypto directory 2022-04-08 16:11:48 +08:00
sm4_generic.c crypto: arm64/sm4-ce - Make dependent on sm4 library instead of sm4-generic 2021-07-30 10:58:30 +08:00
sm4.c crypto: sm4 - export sm4 constant arrays 2022-04-08 16:12:46 +08:00
streebog_generic.c
tcrypt.c crypto: blake2s - remove shash module 2022-06-10 16:43:49 +08:00
tcrypt.h
tea.c
testmgr.c crypto: blake2s - remove shash module 2022-06-10 16:43:49 +08:00
testmgr.h crypto: blake2s - remove shash module 2022-06-10 16:43:49 +08:00
twofish_common.c
twofish_generic.c
vmac.c
wp512.c crypto: wp512 - correct a non-kernel-doc comment 2021-08-12 19:32:17 +08:00
xcbc.c
xctr.c crypto: xctr - Add XCTR support 2022-06-10 16:40:16 +08:00
xor.c
xts.c crypto: xts - Add softdep on ecb 2022-02-18 16:21:08 +11:00
xxhash_generic.c
zstd.c lib: zstd: Add kernel-specific API 2021-11-08 16:55:21 -08:00