mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-10-27 18:20:10 +10:00
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(¶ms)), 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>
|
||
|---|---|---|
| .. | ||
| asymmetric_keys | ||
| async_tx | ||
| 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 | ||
| ahash.c | ||
| akcipher.c | ||
| algapi.c | ||
| algboss.c | ||
| algif_aead.c | ||
| algif_hash.c | ||
| algif_rng.c | ||
| algif_skcipher.c | ||
| ansi_cprng.c | ||
| anubis.c | ||
| api.c | ||
| arc4.c | ||
| authenc.c | ||
| 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 | ||
| chacha20poly1305.c | ||
| chacha_generic.c | ||
| cipher.c | ||
| cmac.c | ||
| compress.c | ||
| crc32_generic.c | ||
| crc32c_generic.c | ||
| crc64_rocksoft_generic.c | ||
| crct10dif_common.c | ||
| crct10dif_generic.c | ||
| cryptd.c | ||
| crypto_engine.c | ||
| 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 | ||
| dh.c | ||
| drbg.c | ||
| ecb.c | ||
| ecc_curve_defs.h | ||
| ecc.c | ||
| ecdh_helper.c | ||
| ecdh.c | ||
| ecdsa.c | ||
| ecdsasignature.asn1 | ||
| echainiv.c | ||
| ecrdsa_defs.h | ||
| ecrdsa_params.asn1 | ||
| ecrdsa_pub_key.asn1 | ||
| ecrdsa.c | ||
| essiv.c | ||
| fcrypt.c | ||
| fips.c | ||
| gcm.c | ||
| geniv.c | ||
| gf128mul.c | ||
| ghash-generic.c | ||
| hash_info.c | ||
| hctr2.c | ||
| hmac.c | ||
| internal.h | ||
| jitterentropy-kcapi.c | ||
| jitterentropy.c | ||
| jitterentropy.h | ||
| Kconfig | ||
| kdf_sp800108.c | ||
| keywrap.c | ||
| khazad.c | ||
| kpp.c | ||
| lrw.c | ||
| lz4.c | ||
| lz4hc.c | ||
| lzo-rle.c | ||
| lzo.c | ||
| Makefile | ||
| md4.c | ||
| md5.c | ||
| michael_mic.c | ||
| nhpoly1305.c | ||
| ofb.c | ||
| pcbc.c | ||
| pcrypt.c | ||
| poly1305_generic.c | ||
| polyval-generic.c | ||
| proc.c | ||
| ripemd.h | ||
| rmd160.c | ||
| rng.c | ||
| rsa_helper.c | ||
| rsa-pkcs1pad.c | ||
| rsa.c | ||
| rsaprivkey.asn1 | ||
| rsapubkey.asn1 | ||
| scatterwalk.c | ||
| scompress.c | ||
| seed.c | ||
| seqiv.c | ||
| serpent_generic.c | ||
| sha1_generic.c | ||
| sha3_generic.c | ||
| sha256_generic.c | ||
| sha512_generic.c | ||
| shash.c | ||
| simd.c | ||
| skcipher.c | ||
| sm2.c | ||
| sm2signature.asn1 | ||
| sm3_generic.c | ||
| sm3.c | ||
| sm4_generic.c | ||
| sm4.c | ||
| streebog_generic.c | ||
| tcrypt.c | ||
| tcrypt.h | ||
| tea.c | ||
| testmgr.c | ||
| testmgr.h | ||
| twofish_common.c | ||
| twofish_generic.c | ||
| vmac.c | ||
| wp512.c | ||
| xcbc.c | ||
| xctr.c | ||
| xor.c | ||
| xts.c | ||
| xxhash_generic.c | ||
| zstd.c | ||