From 75145cd1ee18605181abfa40001fa3c483317b75 Mon Sep 17 00:00:00 2001 From: armfazh Date: Mon, 18 Mar 2024 12:27:23 -0700 Subject: [PATCH] Benchmark in-kernel verification. --- zeta/rsa_bench/Makefile | 9 ++++-- zeta/rsa_bench/go.mod | 3 ++ zeta/rsa_bench/rsa.go | 33 +++++++++++++++++++-- zeta/rsa_bench/rsa_test.go | 59 +++++++++++++++++++++++++++++++------- 4 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 zeta/rsa_bench/go.mod diff --git a/zeta/rsa_bench/Makefile b/zeta/rsa_bench/Makefile index d221307a1e289..bad565b983d0f 100644 --- a/zeta/rsa_bench/Makefile +++ b/zeta/rsa_bench/Makefile @@ -4,10 +4,15 @@ compile: rsa.go rsa_test.go go build -o example.exe go test -c -o bench.exe -example: example.exe +load_parser: + modprobe pkcs8_key_parser + +example: rsa.go + go build -o example.exe ./example.exe -benchmark: bench.exe +benchmark: rsa.go rsa_test.go + go test -c -o bench.exe ./bench.exe -test.v -test.bench=. clean: diff --git a/zeta/rsa_bench/go.mod b/zeta/rsa_bench/go.mod new file mode 100644 index 0000000000000..1811bc1db71ea --- /dev/null +++ b/zeta/rsa_bench/go.mod @@ -0,0 +1,3 @@ +module cloudflare.com/linux/rsa_bench + +go 1.22.0 diff --git a/zeta/rsa_bench/rsa.go b/zeta/rsa_bench/rsa.go index 386c5ba7299b4..2c51139778e2e 100644 --- a/zeta/rsa_bench/rsa.go +++ b/zeta/rsa_bench/rsa.go @@ -13,10 +13,12 @@ import ( type KeySerial int32 type Keyring int32 +type KeyOps = uintptr const ( KEY_SPEC_PROCESS_KEYRING Keyring = -2 - KEYCTL_PKEY_SIGN = 27 + KEYCTL_PKEY_SIGN KeyOps = 27 + KEYCTL_PKEY_VERIFY KeyOps = 28 ) var ( @@ -70,6 +72,27 @@ func (key KeySerial) Sign(info, digest, signature []byte) error { return errno } +func (key KeySerial) Verify(info, digest, signature []byte) error { + var params pkeyParams + params.key_id = key + params.in_len = uint32(len(digest)) + params.out_or_in2_len = uint32(len(signature)) + + _, _, errno := syscall.Syscall6( + syscall.SYS_KEYCTL, KEYCTL_PKEY_VERIFY, + uintptr(unsafe.Pointer(¶ms)), + uintptr(unsafe.Pointer(&info[0])), + uintptr(unsafe.Pointer(&digest[0])), + uintptr(unsafe.Pointer(&signature[0])), + uintptr(0), + ) + if errno == 0 { + return nil + } + + return errno +} + func loadKeyToKernel(key crypto.PrivateKey) KeySerial { pkcs8, err := x509.MarshalPKCS8PrivateKey(key) if err != nil { @@ -108,8 +131,14 @@ func main() { } log.Printf("Signature from Kernel: %x...", signature[:10]) + err = keyInKernel.Verify(sha256pkcs1, digest[:], signature[:]) + if err != nil { + log.Fatalf("failed to verify the digest: %v", err) + } + log.Printf("Valid signature from Kernel: %v", err == nil) + err = rsa.VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, digest[:], signature[:]) - log.Printf("Valid signature: %v", err == nil) + log.Printf("Valid signature from Go: %v", err == nil) if err != nil { log.Fatalf("failed to verify the signature: %v", err) } diff --git a/zeta/rsa_bench/rsa_test.go b/zeta/rsa_bench/rsa_test.go index 77396febe4117..853ca6644e73e 100644 --- a/zeta/rsa_bench/rsa_test.go +++ b/zeta/rsa_bench/rsa_test.go @@ -5,11 +5,10 @@ import ( "crypto/rand" "crypto/rsa" "crypto/sha256" - "log" "testing" ) -func BenchmarkRSAKernel(b *testing.B) { +func kernelSetup(b *testing.B) (KeySerial, []byte, []byte) { const N = 2048 var ( @@ -20,16 +19,39 @@ func BenchmarkRSAKernel(b *testing.B) { priv, err := rsa.GenerateKey(rand.Reader, N) if err != nil { - log.Fatalf("failed to generate private key: %v", err) + b.Fatalf("failed to generate private key: %v", err) } keyInKernel := loadKeyToKernel(priv) + return keyInKernel, digest[:], signature[:] +} + +func BenchmarkRSAKernelSign(b *testing.B) { + keyInKernel, digest, signature := kernelSetup(b) + b.ResetTimer() for i := 0; i < b.N; i++ { err := keyInKernel.Sign(sha256pkcs1, digest[:], signature[:]) if err != nil { - log.Fatalf("failed to sign the digest: %v", err) + b.Fatalf("failed to sign the digest: %v", err) + } + } +} + +func BenchmarkRSAKernelVerify(b *testing.B) { + keyInKernel, digest, signature := kernelSetup(b) + + err := keyInKernel.Sign(sha256pkcs1, digest[:], signature[:]) + if err != nil { + b.Fatalf("failed to sign the digest: %v", err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + err := keyInKernel.Verify(sha256pkcs1, digest[:], signature[:]) + if err != nil { + b.Fatalf("failed to sign the digest: %v", err) } } } @@ -44,14 +66,29 @@ func BenchmarkRSAGo(b *testing.B) { priv, err := rsa.GenerateKey(rand.Reader, N) if err != nil { - log.Fatalf("failed to generate private key: %v", err) + b.Fatalf("failed to generate private key: %v", err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := priv.Sign(rand.Reader, digest[:], crypto.SHA256) - if err != nil { - log.Fatalf("failed to sign the digest: %v", err) - } + signature, err := priv.Sign(rand.Reader, digest[:], crypto.SHA256) + if err != nil { + b.Fatalf("failed to sign the digest: %v", err) } + + b.Run("Sign", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, err := priv.Sign(rand.Reader, digest[:], crypto.SHA256) + if err != nil { + b.Fatalf("failed to sign the digest: %v", err) + } + } + }) + + b.Run("Verify", func(b *testing.B) { + for i := 0; i < b.N; i++ { + err := rsa.VerifyPKCS1v15(&priv.PublicKey, crypto.SHA256, digest[:], signature[:]) + if err != nil { + b.Fatalf("failed to sign the digest: %v", err) + } + } + }) }