diff --git a/const.go b/const.go index 510e2ad1..8b6393fe 100644 --- a/const.go +++ b/const.go @@ -42,6 +42,7 @@ const ( //checkheader:ignore _KeyTypeRSA cString = "RSA\x00" _KeyTypeEC cString = "EC\x00" _KeyTypeED25519 cString = "ED25519\x00" + _KeyTypeX25519 cString = "X25519\x00" _KeyTypeMLKEM768 cString = "ML-KEM-768\x00" _KeyTypeMLKEM1024 cString = "ML-KEM-1024\x00" diff --git a/ec.go b/ec.go index 86009c7f..ef1a181f 100644 --- a/ec.go +++ b/ec.go @@ -2,7 +2,55 @@ package openssl -import "github.com/golang-fips/openssl/v2/internal/ossl" +import ( + "errors" + "strconv" + "sync" + + "github.com/golang-fips/openssl/v2/internal/ossl" +) + +func SupportsCurve(curve string) bool { + switch curve { + case "P-224", "P-256", "P-384", "P-521": + return true + case "X25519": + return supportsX25519() + default: + return false + } +} + +var supportsX25519 = sync.OnceValue(func() bool { + if !versionAtOrAbove(1, 1, 1) { + // X25519 support was added in OpenSSL 1.1.0, but the APIs we use + // to implement it were only added in 1.1.1. + return false + } + ctx, _ := ossl.EVP_PKEY_CTX_new_id(ossl.EVP_PKEY_X25519, nil) + if ctx != nil { + ossl.EVP_PKEY_CTX_free(ctx) + return true + } + return false +}) + +func curveID(curve string) int32 { + switch curve { + case "P-224": + return ossl.EVP_PKEY_EC + case "P-256": + return ossl.EVP_PKEY_EC + case "P-384": + return ossl.EVP_PKEY_EC + case "P-521": + return ossl.EVP_PKEY_EC + case "X25519": + return ossl.EVP_PKEY_X25519 + default: + panic("openssl: unknown curve " + curve) + } +} func curveNID(curve string) int32 { switch curve { @@ -64,3 +112,25 @@ func generateAndEncodeEcPublicKey(nid int32, newPubKeyPointFn func(group ossl.EC defer ossl.EC_POINT_free(pt) return encodeEcPoint(group, pt) } + +func extractPKEYRawPublic(pkey ossl.EVP_PKEY_PTR, pub []byte) error { + keylen := len(pub) + if _, err := ossl.EVP_PKEY_get_raw_public_key(pkey, base(pub), &keylen); err != nil { + return err + } + if keylen != len(pub) { + return errors.New("bad public key length: " + strconv.Itoa(keylen)) + } + return nil +} + +func extractPKEYRawPrivate(pkey ossl.EVP_PKEY_PTR, pub []byte) error { + keylen := len(pub) + if _, err := ossl.EVP_PKEY_get_raw_private_key(pkey, base(pub), &keylen); err != nil { + return err + } + if keylen != len(pub) { + return errors.New("bad private key length: " + strconv.Itoa(keylen)) + } + return nil +} diff --git a/ecdh.go b/ecdh.go index 13c8e1e1..c95b3235 100644 --- a/ecdh.go +++ b/ecdh.go @@ -11,6 +11,9 @@ import ( "github.com/golang-fips/openssl/v2/internal/ossl" ) +const publicKeySizeX25519 = 32 +const privateKeySizeX25519 = 32 + type PublicKeyECDH struct { _pkey ossl.EVP_PKEY_PTR bytes []byte @@ -30,9 +33,14 @@ func (k *PrivateKeyECDH) finalize() { } func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { - if len(bytes) != 1+2*curveSize(curve) { + expectedLen := publicKeySizeX25519 + if curve != "X25519" { + expectedLen = 1 + 2*curveSize(curve) + } + if len(bytes) != expectedLen { return nil, errors.New("NewPublicKeyECDH: wrong key length") } + pkey, err := newECDHPkey(curve, bytes, false) if err != nil { return nil, err @@ -45,7 +53,11 @@ func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { func (k *PublicKeyECDH) Bytes() []byte { return k.bytes } func NewPrivateKeyECDH(curve string, bytes []byte) (*PrivateKeyECDH, error) { - if len(bytes) != curveSize(curve) { + expectedLen := privateKeySizeX25519 + if curve != "X25519" { + expectedLen = curveSize(curve) + } + if len(bytes) != expectedLen { return nil, errors.New("NewPrivateKeyECDH: wrong key length") } pkey, err := newECDHPkey(curve, bytes, true) @@ -65,40 +77,50 @@ func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { }() var bytes []byte - switch vMajor { - case 1: - var err error - pkey, err = ossl.EVP_PKEY_new() - if err != nil { - return nil, err - } - key := getECKey(k._pkey) - if _, err := ossl.EVP_PKEY_set1_EC_KEY(pkey, key); err != nil { - return nil, err - } - pt := ossl.EC_KEY_get0_public_key(key) - if pt == nil { - return nil, fail("missing ECDH public key") - } - group := ossl.EC_KEY_get0_group(key) - if bytes, err = encodeEcPoint(group, pt); err != nil { - return nil, err - } - case 3: + if k.curve == "X25519" { pkey = k._pkey if _, err := ossl.EVP_PKEY_up_ref(pkey); err != nil { return nil, err } - - var cbytes *byte - n, err := ossl.EVP_PKEY_get1_encoded_public_key(k._pkey, &cbytes) - if err != nil { + bytes = make([]byte, publicKeySizeX25519) + if err := extractPKEYRawPublic(pkey, bytes); err != nil { return nil, err } - bytes = goBytes(unsafe.Pointer(cbytes), n) - cryptoFree(unsafe.Pointer(cbytes)) - default: - panic(errUnsupportedVersion()) + } else { + switch vMajor { + case 1: + var err error + pkey, err = ossl.EVP_PKEY_new() + if err != nil { + return nil, err + } + key := getECKey(k._pkey) + if _, err := ossl.EVP_PKEY_set1_EC_KEY(pkey, key); err != nil { + return nil, err + } + pt := ossl.EC_KEY_get0_public_key(key) + if pt == nil { + return nil, fail("missing ECDH public key") + } + group := ossl.EC_KEY_get0_group(key) + if bytes, err = encodeEcPoint(group, pt); err != nil { + return nil, err + } + case 3: + pkey = k._pkey + if _, err := ossl.EVP_PKEY_up_ref(pkey); err != nil { + return nil, err + } + var cbytes *byte + n, err := ossl.EVP_PKEY_get1_encoded_public_key(k._pkey, &cbytes) + if err != nil { + return nil, err + } + bytes = goBytes(unsafe.Pointer(cbytes), n) + cryptoFree(unsafe.Pointer(cbytes)) + default: + panic(errUnsupportedVersion()) + } } pub := &PublicKeyECDH{pkey, bytes} pkey = nil @@ -107,6 +129,13 @@ func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { } func newECDHPkey(curve string, bytes []byte, isPrivate bool) (ossl.EVP_PKEY_PTR, error) { + if curve == "X25519" { + if isPrivate { + return ossl.EVP_PKEY_new_raw_private_key(ossl.EVP_PKEY_X25519, nil, base(bytes), len(bytes)) + } else { + return ossl.EVP_PKEY_new_raw_public_key(ossl.EVP_PKEY_X25519, nil, base(bytes), len(bytes)) + } + } nid := curveNID(curve) switch vMajor { case 1: @@ -260,7 +289,7 @@ func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { } func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { - pkey, err := generateEVPPKey(ossl.EVP_PKEY_EC, 0, curve) + pkey, err := generateEVPPKey(curveID(curve), 0, curve) if err != nil { return nil, nil, err } @@ -270,34 +299,43 @@ func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { ossl.EVP_PKEY_free(pkey) } }() - var priv ossl.BIGNUM_PTR - switch vMajor { - case 1: - key := getECKey(pkey) - priv = ossl.EC_KEY_get0_private_key(key) - if priv == nil { - return nil, nil, fail("missing ECDH private key") + var bytes []byte + if curve == "X25519" { + bytes = make([]byte, privateKeySizeX25519) + keylen := len(bytes) + if _, err := ossl.EVP_PKEY_get_raw_private_key(pkey, base(bytes), &keylen); err != nil { + return nil, nil, err } - case 3: - if _, err := ossl.EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PRIV_KEY.ptr(), &priv); err != nil { + } else { + var priv ossl.BIGNUM_PTR + switch vMajor { + case 1: + key := getECKey(pkey) + priv = ossl.EC_KEY_get0_private_key(key) + if priv == nil { + return nil, nil, fail("missing ECDH private key") + } + case 3: + if _, err := ossl.EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PRIV_KEY.ptr(), &priv); err != nil { + return nil, nil, err + } + defer ossl.BN_clear_free(priv) + default: + panic(errUnsupportedVersion()) + } + // We should not leak bit length of the secret scalar in the key. + // For this reason, we use BN_bn2binpad instead of BN_bn2bin with fixed length. + // The fixed length is the order of the large prime subgroup of the curve, + // returned by EVP_PKEY_get_bits, which is generally the upper bound for + // generating a private ECDH key. + bits, err := ossl.EVP_PKEY_get_bits(pkey) + if err != nil { + return nil, nil, err + } + bytes = make([]byte, (bits+7)/8) + if err := bnToBinPad(priv, bytes); err != nil { return nil, nil, err } - defer ossl.BN_clear_free(priv) - default: - panic(errUnsupportedVersion()) - } - // We should not leak bit length of the secret scalar in the key. - // For this reason, we use BN_bn2binpad instead of BN_bn2bin with fixed length. - // The fixed length is the order of the large prime subgroup of the curve, - // returned by EVP_PKEY_get_bits, which is generally the upper bound for - // generating a private ECDH key. - bits, err := ossl.EVP_PKEY_get_bits(pkey) - if err != nil { - return nil, nil, err - } - bytes := make([]byte, (bits+7)/8) - if err := bnToBinPad(priv, bytes); err != nil { - return nil, nil, err } k = &PrivateKeyECDH{pkey, curve} runtime.SetFinalizer(k, (*PrivateKeyECDH).finalize) diff --git a/ecdh_test.go b/ecdh_test.go index da1e37f3..dced7f2e 100644 --- a/ecdh_test.go +++ b/ecdh_test.go @@ -2,6 +2,7 @@ package openssl_test import ( "bytes" + "crypto/rand" "encoding/hex" "strings" "testing" @@ -10,9 +11,10 @@ import ( ) func TestECDH(t *testing.T) { - for _, tt := range []string{"P-256", "P-384", "P-521"} { + for _, tt := range []string{"P-256", "P-384", "P-521", "X25519"} { t.Run(tt, func(t *testing.T) { name := tt + skipUnsupportedCurve(t, name) aliceKey, alicPrivBytes, err := openssl.GenerateKeyECDH(name) if err != nil { t.Fatal(err) @@ -107,11 +109,20 @@ var ecdhvectors = []struct { "01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676", SharedSecret: "005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831", }, + // X25519 test vector from RFC 7748, Section 6.1. + { + Name: "X25519", + PrivateKey: "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a", + PublicKey: "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a", + PeerPublicKey: "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f", + SharedSecret: "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742", + }, } func TestECDHVectors(t *testing.T) { for _, tt := range ecdhvectors { t.Run(tt.Name, func(t *testing.T) { + skipUnsupportedCurve(t, tt.Name) key, err := openssl.NewPrivateKeyECDH(tt.Name, hexDecode(t, tt.PrivateKey)) if err != nil { t.Fatal(err) @@ -217,6 +228,14 @@ var invalidECDHPrivateKeys = map[string][]string{ "11fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", "03fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4a30d0f077e5f2cd6ff980291ee134ba0776b937113388f5d76df6e3d2270c812", }, + "X25519": { + // X25519 only rejects bad lengths. + "", + "01", + "01010101010101010101010101010101010101010101010101010101010101", + "000101010101010101010101010101010101010101010101010101010101010101", + strings.Repeat("01", 200), + }, } var invalidECDHPublicKeys = map[string][]string{ @@ -262,11 +281,13 @@ var invalidECDHPublicKeys = map[string][]string{ "0400c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16651", "04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", }, + "X25519": {}, } func TestECDHNewPrivateKeyECDH_Invalid(t *testing.T) { - for _, curve := range []string{"P-256", "P-384", "P-521"} { + for _, curve := range []string{"P-256", "P-384", "P-521", "X25519"} { t.Run(curve, func(t *testing.T) { + skipUnsupportedCurve(t, curve) for _, input := range invalidECDHPrivateKeys[curve] { k, err := openssl.NewPrivateKeyECDH(curve, hexDecode(t, input)) if err == nil { @@ -280,8 +301,9 @@ func TestECDHNewPrivateKeyECDH_Invalid(t *testing.T) { } func TestECDHNewPublicKeyECDH_Invalid(t *testing.T) { - for _, curve := range []string{"P-256", "P-384", "P-521"} { + for _, curve := range []string{"P-256", "P-384", "P-521", "X25519"} { t.Run(curve, func(t *testing.T) { + skipUnsupportedCurve(t, curve) for _, input := range invalidECDHPublicKeys[curve] { k, err := openssl.NewPublicKeyECDH(curve, hexDecode(t, input)) if err == nil { @@ -293,3 +315,40 @@ func TestECDHNewPublicKeyECDH_Invalid(t *testing.T) { }) } } + +func TestX25519Failure(t *testing.T) { + skipUnsupportedCurve(t, "X25519") + identity := hexDecode(t, "0000000000000000000000000000000000000000000000000000000000000000") + lowOrderPoint := hexDecode(t, "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800") + randomScalar := make([]byte, 32) + rand.Read(randomScalar) + + t.Run("identity point", func(t *testing.T) { testX25519Failure(t, randomScalar, identity) }) + t.Run("low order point", func(t *testing.T) { testX25519Failure(t, randomScalar, lowOrderPoint) }) +} + +func testX25519Failure(t *testing.T, private, public []byte) { + priv, err := openssl.NewPrivateKeyECDH("X25519", private) + if err != nil { + t.Fatal(err) + } + pub, err := openssl.NewPublicKeyECDH("X25519", public) + if err != nil { + // Some providers may reject the public key at import time. + return + } + secret, err := openssl.ECDH(priv, pub) + if err == nil { + t.Error("expected ECDH error") + } + if secret != nil { + t.Errorf("unexpected ECDH output: %x", secret) + } +} + +func skipUnsupportedCurve(t *testing.T, curve string) { + t.Helper() + if !openssl.SupportsCurve(curve) { + t.Skipf("skipping test: curve %q is not supported", curve) + } +} diff --git a/ed25519.go b/ed25519.go index d160bbe2..bafc9794 100644 --- a/ed25519.go +++ b/ed25519.go @@ -62,7 +62,7 @@ func (k *PublicKeyEd25519) finalize() { func (k *PublicKeyEd25519) Bytes() ([]byte, error) { defer runtime.KeepAlive(k) pub := make([]byte, publicKeySizeEd25519) - if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { + if err := extractPKEYRawPublic(k._pkey, pub); err != nil { return nil, err } return pub, nil @@ -87,7 +87,7 @@ func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { func (k *PrivateKeyEd25519) Public() (*PublicKeyEd25519, error) { pub := make([]byte, publicKeySizeEd25519) - if err := extractPKEYPubEd25519(k._pkey, pub); err != nil { + if err := extractPKEYRawPublic(k._pkey, pub); err != nil { return nil, err } pubk, err := NewPublicKeyEd25519(pub) @@ -154,29 +154,11 @@ func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) { return priv, nil } -func extractPKEYPubEd25519(pkey ossl.EVP_PKEY_PTR, pub []byte) error { - keylen := publicKeySizeEd25519 - if _, err := ossl.EVP_PKEY_get_raw_public_key(pkey, base(pub), &keylen); err != nil { - return err - } - if keylen != publicKeySizeEd25519 { - return errors.New("ed25519: bad public key length: " + strconv.Itoa(keylen)) - } - return nil -} - func extractPKEYPrivEd25519(pkey ossl.EVP_PKEY_PTR, priv []byte) error { - if err := extractPKEYPubEd25519(pkey, priv[seedSizeEd25519:]); err != nil { - return err - } - keylen := seedSizeEd25519 - if _, err := ossl.EVP_PKEY_get_raw_private_key(pkey, base(priv), &keylen); err != nil { + if err := extractPKEYRawPublic(pkey, priv[seedSizeEd25519:]); err != nil { return err } - if keylen != seedSizeEd25519 { - return errors.New("ed25519: bad private key length: " + strconv.Itoa(keylen)) - } - return nil + return extractPKEYRawPrivate(pkey, priv[:seedSizeEd25519]) } // SignEd25519 signs the message with priv and returns a signature. diff --git a/evp.go b/evp.go index db9646c8..1e048be6 100644 --- a/evp.go +++ b/evp.go @@ -227,7 +227,7 @@ func generateEVPPKey(id, bits int32, curve string) (ossl.EVP_PKEY_PTR, error) { return nil, err } } - if curve != "" { + if id == ossl.EVP_PKEY_EC && curve != "" { if _, err := ossl.EVP_PKEY_CTX_ctrl(ctx, id, -1, ossl.EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, curveNID(curve), nil); err != nil { return nil, err } @@ -244,6 +244,8 @@ func generateEVPPKey(id, bits int32, curve string) (ossl.EVP_PKEY_PTR, error) { pkey, err = ossl.EVP_PKEY_Q_keygen_EC(nil, nil, _KeyTypeEC.ptr(), ossl.OBJ_nid2sn(curveNID(curve))) case ossl.EVP_PKEY_ED25519: pkey, err = ossl.EVP_PKEY_Q_keygen_ED25519(nil, nil, _KeyTypeED25519.ptr()) + case ossl.EVP_PKEY_X25519: + pkey, err = ossl.EVP_PKEY_Q_keygen_X25519(nil, nil, _KeyTypeX25519.ptr()) case ossl.EVP_PKEY_MLKEM_768: pkey, err = ossl.EVP_PKEY_Q_keygen_MLKEM(nil, nil, _KeyTypeMLKEM768.ptr()) case ossl.EVP_PKEY_MLKEM_1024: diff --git a/internal/ossl/shims.h b/internal/ossl/shims.h index 925b256a..07639e7c 100644 --- a/internal/ossl/shims.h +++ b/internal/ossl/shims.h @@ -44,6 +44,7 @@ enum { _EVP_PKEY_RSA = 6, _EVP_PKEY_EC = 408, _EVP_PKEY_TLS1_PRF = 1021, + _EVP_PKEY_X25519 = 1034, _EVP_PKEY_HKDF = 1036, _EVP_PKEY_ED25519 = 1087, _EVP_PKEY_DSA = 116, @@ -283,7 +284,7 @@ int EVP_PKEY_set1_encoded_public_key(_EVP_PKEY_PTR pkey, const unsigned char *pu size_t EVP_PKEY_get1_encoded_public_key(_EVP_PKEY_PTR pkey, unsigned char **ppub) __attribute__((tag("3"))); int EVP_PKEY_get_bn_param(const _EVP_PKEY_PTR pkey, const char *key_name, _BIGNUM_PTR *bn) __attribute__((tag("3"))); int EVP_PKEY_get_octet_string_param(const _EVP_PKEY_PTR pkey, const char *key_name, unsigned char *buf, size_t buf_len, size_t *out_len) __attribute__((tag("3"))); -int EVP_PKEY_up_ref(_EVP_PKEY_PTR key) __attribute__((tag("3"))); +int EVP_PKEY_up_ref(_EVP_PKEY_PTR key); int EVP_PKEY_set1_EC_KEY(_EVP_PKEY_PTR pkey, _EC_KEY_PTR key) __attribute__((tag("legacy_1"))); int EVP_PKEY_CTX_set0_rsa_oaep_label(_EVP_PKEY_CTX_PTR ctx, void *label, int len) __attribute__((tag("3"))); int EVP_PKEY_get_raw_public_key(const _EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len) __attribute__((tag("111"),noescape,nocallback)); @@ -311,6 +312,7 @@ _EVP_PKEY_PTR EVP_PKEY_Q_keygen(_OSSL_LIB_CTX_PTR ctx, const char *propq, const _EVP_PKEY_PTR EVP_PKEY_Q_keygen_RSA(_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type, size_t arg1) __attribute__((tag("3"),variadic("EVP_PKEY_Q_keygen"))); _EVP_PKEY_PTR EVP_PKEY_Q_keygen_EC(_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type, const char *arg1) __attribute__((tag("3"),variadic("EVP_PKEY_Q_keygen"))); _EVP_PKEY_PTR EVP_PKEY_Q_keygen_ED25519(_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type) __attribute__((tag("3"),variadic("EVP_PKEY_Q_keygen"))); +_EVP_PKEY_PTR EVP_PKEY_Q_keygen_X25519(_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type) __attribute__((tag("3"),variadic("EVP_PKEY_Q_keygen"))); _EVP_PKEY_PTR EVP_PKEY_Q_keygen_MLKEM(_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type) __attribute__((tag("3"),variadic("EVP_PKEY_Q_keygen"))); _EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new(_EVP_PKEY_PTR arg0, _ENGINE_PTR arg1); diff --git a/internal/ossl/zossl.c b/internal/ossl/zossl.c index b24f0a2d..45df4fbf 100644 --- a/internal/ossl/zossl.c +++ b/internal/ossl/zossl.c @@ -321,6 +321,7 @@ void __mkcgo_load_(void* handle) { __mkcgo__dlsym(EVP_PKEY_paramgen_init) __mkcgo__dlsym(EVP_PKEY_sign) __mkcgo__dlsym(EVP_PKEY_sign_init) + __mkcgo__dlsym(EVP_PKEY_up_ref) __mkcgo__dlsym(EVP_PKEY_verify) __mkcgo__dlsym(EVP_PKEY_verify_init) __mkcgo__dlsym(EVP_aes_128_cbc) @@ -426,6 +427,7 @@ void __mkcgo_unload_() { _g_EVP_PKEY_paramgen_init = NULL; _g_EVP_PKEY_sign = NULL; _g_EVP_PKEY_sign_init = NULL; + _g_EVP_PKEY_up_ref = NULL; _g_EVP_PKEY_verify = NULL; _g_EVP_PKEY_verify_init = NULL; _g_EVP_aes_128_cbc = NULL; @@ -547,7 +549,6 @@ void __mkcgo_load_3(void* handle) { __mkcgo__dlsym(EVP_PKEY_private_check) __mkcgo__dlsym(EVP_PKEY_public_check_quick) __mkcgo__dlsym(EVP_PKEY_set1_encoded_public_key) - __mkcgo__dlsym(EVP_PKEY_up_ref) __mkcgo__dlsym(EVP_SIGNATURE_fetch) __mkcgo__dlsym(EVP_SIGNATURE_free) __mkcgo__dlsym(EVP_default_properties_enable_fips) @@ -621,7 +622,6 @@ void __mkcgo_unload_3() { _g_EVP_PKEY_private_check = NULL; _g_EVP_PKEY_public_check_quick = NULL; _g_EVP_PKEY_set1_encoded_public_key = NULL; - _g_EVP_PKEY_up_ref = NULL; _g_EVP_SIGNATURE_fetch = NULL; _g_EVP_SIGNATURE_free = NULL; _g_EVP_default_properties_enable_fips = NULL; @@ -1402,6 +1402,12 @@ _EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_RSA(_OSSL_LIB_CTX_PTR _arg0, const char* return _ret; } +_EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_X25519(_OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2, uintptr_t *_err_state) { + _EVP_PKEY_PTR _ret = _g_EVP_PKEY_Q_keygen(_arg0, _arg1, _arg2); + if (_ret == NULL) *_err_state = mkcgo_err_retrieve(); + return _ret; +} + int _mkcgo_EVP_PKEY_assign(_EVP_PKEY_PTR _arg0, int _arg1, void* _arg2, uintptr_t *_err_state) { int _ret = _g_EVP_PKEY_assign(_arg0, _arg1, _arg2); if (_ret <= 0) *_err_state = mkcgo_err_retrieve(); diff --git a/internal/ossl/zossl.go b/internal/ossl/zossl.go index 3d66be3b..5f6ed2fa 100644 --- a/internal/ossl/zossl.go +++ b/internal/ossl/zossl.go @@ -14,6 +14,7 @@ const ( EVP_PKEY_RSA = 6 EVP_PKEY_EC = 408 EVP_PKEY_TLS1_PRF = 1021 + EVP_PKEY_X25519 = 1034 EVP_PKEY_HKDF = 1036 EVP_PKEY_ED25519 = 1087 EVP_PKEY_DSA = 116 diff --git a/internal/ossl/zossl.h b/internal/ossl/zossl.h index 2a6c904f..3880f653 100644 --- a/internal/ossl/zossl.h +++ b/internal/ossl/zossl.h @@ -48,6 +48,7 @@ enum { _EVP_PKEY_RSA = 6, _EVP_PKEY_EC = 408, _EVP_PKEY_TLS1_PRF = 1021, + _EVP_PKEY_X25519 = 1034, _EVP_PKEY_HKDF = 1036, _EVP_PKEY_ED25519 = 1087, _EVP_PKEY_DSA = 116, @@ -231,6 +232,7 @@ _EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_EC(_OSSL_LIB_CTX_PTR, const char*, const _EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_ED25519(_OSSL_LIB_CTX_PTR, const char*, const char*, uintptr_t *); _EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_MLKEM(_OSSL_LIB_CTX_PTR, const char*, const char*, uintptr_t *); _EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_RSA(_OSSL_LIB_CTX_PTR, const char*, const char*, size_t, uintptr_t *); +_EVP_PKEY_PTR _mkcgo_EVP_PKEY_Q_keygen_X25519(_OSSL_LIB_CTX_PTR, const char*, const char*, uintptr_t *); int _mkcgo_EVP_PKEY_assign(_EVP_PKEY_PTR, int, void*, uintptr_t *); int _mkcgo_EVP_PKEY_decapsulate(_EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t, uintptr_t *); int _mkcgo_EVP_PKEY_decapsulate_init(_EVP_PKEY_CTX_PTR, const _OSSL_PARAM_PTR, uintptr_t *); diff --git a/internal/ossl/zossl_cgo.go b/internal/ossl/zossl_cgo.go index dd9985c9..ba469a24 100644 --- a/internal/ossl/zossl_cgo.go +++ b/internal/ossl/zossl_cgo.go @@ -725,6 +725,12 @@ func EVP_PKEY_Q_keygen_RSA(ctx OSSL_LIB_CTX_PTR, propq *byte, __type *byte, arg1 return _ret, newMkcgoErr("EVP_PKEY_Q_keygen_RSA", uintptr(_err)) } +func EVP_PKEY_Q_keygen_X25519(ctx OSSL_LIB_CTX_PTR, propq *byte, __type *byte) (EVP_PKEY_PTR, error) { + var _err C.uintptr_t + _ret := C._mkcgo_EVP_PKEY_Q_keygen_X25519(ctx, (*C.char)(unsafe.Pointer(propq)), (*C.char)(unsafe.Pointer(__type)), mkcgoNoEscape(&_err)) + return _ret, newMkcgoErr("EVP_PKEY_Q_keygen_X25519", uintptr(_err)) +} + func EVP_PKEY_assign(pkey EVP_PKEY_PTR, __type int32, key unsafe.Pointer) (int32, error) { var _err C.uintptr_t _ret := C._mkcgo_EVP_PKEY_assign(pkey, C.int(__type), key, mkcgoNoEscape(&_err)) diff --git a/internal/ossl/zossl_nocgo.go b/internal/ossl/zossl_nocgo.go index 324a7f42..39f67a2f 100644 --- a/internal/ossl/zossl_nocgo.go +++ b/internal/ossl/zossl_nocgo.go @@ -912,6 +912,12 @@ func EVP_PKEY_Q_keygen_RSA(ctx OSSL_LIB_CTX_PTR, propq *byte, __type *byte, arg1 return EVP_PKEY_PTR(r0), newMkcgoErr("EVP_PKEY_Q_keygen_RSA", _err) } +func EVP_PKEY_Q_keygen_X25519(ctx OSSL_LIB_CTX_PTR, propq *byte, __type *byte) (EVP_PKEY_PTR, error) { + var _err uintptr + r0, _ := syscallN(1, _mkcgo_EVP_PKEY_Q_keygen, uintptr(ctx), uintptr(unsafe.Pointer(propq)), uintptr(unsafe.Pointer(__type)), uintptr(unsafe.Pointer(&_err))) + return EVP_PKEY_PTR(r0), newMkcgoErr("EVP_PKEY_Q_keygen_X25519", _err) +} + var _mkcgo_EVP_PKEY_assign uintptr func EVP_PKEY_assign(pkey EVP_PKEY_PTR, __type int32, key unsafe.Pointer) (int32, error) { @@ -1875,6 +1881,7 @@ func MkcgoLoad_(handle unsafe.Pointer) { _mkcgo_EVP_PKEY_paramgen_init = dlsym(handle, "EVP_PKEY_paramgen_init\x00", false) _mkcgo_EVP_PKEY_sign = dlsym(handle, "EVP_PKEY_sign\x00", false) _mkcgo_EVP_PKEY_sign_init = dlsym(handle, "EVP_PKEY_sign_init\x00", false) + _mkcgo_EVP_PKEY_up_ref = dlsym(handle, "EVP_PKEY_up_ref\x00", false) _mkcgo_EVP_PKEY_verify = dlsym(handle, "EVP_PKEY_verify\x00", false) _mkcgo_EVP_PKEY_verify_init = dlsym(handle, "EVP_PKEY_verify_init\x00", false) _mkcgo_EVP_aes_128_cbc = dlsym(handle, "EVP_aes_128_cbc\x00", false) @@ -1980,6 +1987,7 @@ func MkcgoUnload_() { _mkcgo_EVP_PKEY_paramgen_init = 0 _mkcgo_EVP_PKEY_sign = 0 _mkcgo_EVP_PKEY_sign_init = 0 + _mkcgo_EVP_PKEY_up_ref = 0 _mkcgo_EVP_PKEY_verify = 0 _mkcgo_EVP_PKEY_verify_init = 0 _mkcgo_EVP_aes_128_cbc = 0 @@ -2101,7 +2109,6 @@ func MkcgoLoad_3(handle unsafe.Pointer) { _mkcgo_EVP_PKEY_private_check = dlsym(handle, "EVP_PKEY_private_check\x00", false) _mkcgo_EVP_PKEY_public_check_quick = dlsym(handle, "EVP_PKEY_public_check_quick\x00", false) _mkcgo_EVP_PKEY_set1_encoded_public_key = dlsym(handle, "EVP_PKEY_set1_encoded_public_key\x00", false) - _mkcgo_EVP_PKEY_up_ref = dlsym(handle, "EVP_PKEY_up_ref\x00", false) _mkcgo_EVP_SIGNATURE_fetch = dlsym(handle, "EVP_SIGNATURE_fetch\x00", false) _mkcgo_EVP_SIGNATURE_free = dlsym(handle, "EVP_SIGNATURE_free\x00", false) _mkcgo_EVP_default_properties_enable_fips = dlsym(handle, "EVP_default_properties_enable_fips\x00", false) @@ -2175,7 +2182,6 @@ func MkcgoUnload_3() { _mkcgo_EVP_PKEY_private_check = 0 _mkcgo_EVP_PKEY_public_check_quick = 0 _mkcgo_EVP_PKEY_set1_encoded_public_key = 0 - _mkcgo_EVP_PKEY_up_ref = 0 _mkcgo_EVP_SIGNATURE_fetch = 0 _mkcgo_EVP_SIGNATURE_free = 0 _mkcgo_EVP_default_properties_enable_fips = 0