Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define int constants in Go instead of in C #256

Merged
merged 6 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ jobs:
run: sudo sh ./scripts/openssl.sh ${{ matrix.openssl-version }}
- name: Check headers
working-directory: ./cmd/checkheader
run: go run . --ossl-include /usr/local/src/openssl-${{ matrix.openssl-version }}/include -shim ../../shims.h
run: |
go run . --ossl-include /usr/local/src/openssl-${{ matrix.openssl-version }}/include -shim ../../shims.h
go run . --ossl-include /usr/local/src/openssl-${{ matrix.openssl-version }}/include -shim ../../const.go
- name: Set OpenSSL config and prove FIPS
run: |
sudo cp ./scripts/openssl-3.cnf /usr/local/ssl/openssl.cnf
Expand Down
29 changes: 13 additions & 16 deletions cmd/checkheader/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import (
// - Blank lines are discarded.
// - Comments are discarded unless they contain a C directive, i.e #include, #if or #endif. The directive in the comment is included in the output.
// - Typedefs following the pattern "typedef void* GO_%name%_PTR" are translated into "#define %name% GO_%name%_PTR".
// - Enums are validated against their definition in the OpenSSL headers. Example:
// "enum { GO_EVP_CTRL_GCM_SET_TAG = 0x11 }" => "_Static_assert(EVP_CTRL_GCM_SET_TAG == 0x11);"
// - Go constants are validated against their definition in the OpenSSL headers. Example:
// "const { _EVP_CTRL_GCM_SET_TAG = 0x11 }" => "_Static_assert(EVP_CTRL_GCM_SET_TAG == 0x11);"
// - Function macros are validated against their definition in the OpenSSL headers. Example:
// "DEFINEFUNC(int, RAND_bytes, (unsigned char *a0, int a1), (a0, a1))" => "int(*__check_0)(unsigned char *, int) = RAND_bytes;"
// - Function macros are excluded when checking old OpenSSL versions if they are prepended with '/*check:from=%version%*/', %version% being a version string such as '1.1.1' or '3.0.0'.
Expand Down Expand Up @@ -113,14 +113,14 @@ func generate(header string) (string, error) {
for sc.Scan() {
l := strings.TrimSpace(sc.Text())
if enum {
if !strings.HasPrefix(l, "}") {
tryConvertEnum(&b, l)
if !strings.HasPrefix(l, ")") {
tryConvertGoConst(&b, l)
} else {
enum = false
}
continue
}
if strings.HasPrefix(l, "enum {") || strings.HasPrefix(l, "typedef enum {") {
if l == "const (" {
enum = true
continue
}
Expand Down Expand Up @@ -169,25 +169,22 @@ func tryConvertTypedef(w io.Writer, l string) bool {
return true
}

// tryConvertEnum adds a static check which verifies that
// the enum contained in the line l
// tryConvertGoConst adds a static check which verifies that
// the const contained in the line l
// matches the corresponding OpenSSL value.
// Only enum names starting with GO_ are converted.
func tryConvertEnum(w io.Writer, l string) {
if !strings.HasPrefix(l, "GO_") {
// Only const names starting with _ are converted.
func tryConvertGoConst(w io.Writer, l string) {
if !strings.HasPrefix(l, "_") || strings.HasSuffix(l, "// nocheck") {
return
}
if l[len(l)-1] == ',' {
l = l[:len(l)-1]
}
split := strings.SplitN(l, " = ", 2)
split := strings.Split(l, " ")
if len(split) < 2 {
log.Printf("unexpected enum definition in function line: %s\n", l)
return
}
name := split[0][len("GO_"):]
name := split[0][len("_"):]
fmt.Fprintf(w, "#ifdef %s\n", name)
fmt.Fprintf(w, "_Static_assert(%s == %s, \"%s\");\n", name, split[1], name)
fmt.Fprintf(w, "_Static_assert(%s == %s, \"%s\");\n", name, split[len(split)-1], name)
fmt.Fprintln(w, "#endif")
}

Expand Down
74 changes: 73 additions & 1 deletion const.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (s cString) ptr() *C.char {
return (*C.char)(unsafe.Pointer(unsafe.StringData(string(s))))
}

const (
const ( // no_check
// Provider names
_ProviderNameFips cString = "fips\x00"
_ProviderNameDefault cString = "default\x00"
Expand Down Expand Up @@ -85,3 +85,75 @@ const (
// MAC parameters
_OSSL_MAC_PARAM_DIGEST cString = "digest\x00"
)

// #include <openssl/crypto.h>
// #include <openssl/evp.h>
// #include <openssl/ec.h>
// #include <openssl/kdf.h>
// #include <openssl/obj_mac.h>
// #include <openssl/rsa.h>
// #if OPENSSL_VERSION_NUMBER >= 0x30000000L
// #include <openssl/core_names.h>
// #endif

const (
_POINT_CONVERSION_UNCOMPRESSED = 4

_OPENSSL_INIT_LOAD_CRYPTO_STRINGS = 0x00000002
_OPENSSL_INIT_ADD_ALL_CIPHERS = 0x00000004
_OPENSSL_INIT_ADD_ALL_DIGESTS = 0x00000008
_OPENSSL_INIT_LOAD_CONFIG = 0x00000040

_EVP_CTRL_GCM_GET_TAG = 0x10
_EVP_CTRL_GCM_SET_TAG = 0x11
_EVP_PKEY_CTRL_MD = 1
_EVP_PKEY_RSA = 6
_EVP_PKEY_EC = 408
_EVP_PKEY_TLS1_PRF = 1021
_EVP_PKEY_HKDF = 1036
_EVP_PKEY_ED25519 = 1087
_EVP_PKEY_DSA = 116
// This is defined differently in OpenSSL 3 (1 << 11),
// but in our code it is only used in OpenSSL 1.
_EVP_PKEY_OP_DERIVE = (1 << 10) // nocheck
_EVP_MAX_MD_SIZE = 64

_EVP_PKEY_PUBLIC_KEY = 0x86
_EVP_PKEY_KEYPAIR = 0x87

_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = 0x1001

_EVP_KDF_HKDF_MODE_EXTRACT_ONLY = 1
_EVP_KDF_HKDF_MODE_EXPAND_ONLY = 2

_EVP_PKEY_CTRL_TLS_MD = 0x1000
_EVP_PKEY_CTRL_TLS_SECRET = 0x1001
_EVP_PKEY_CTRL_TLS_SEED = 0x1002
_EVP_PKEY_CTRL_HKDF_MD = 0x1003
_EVP_PKEY_CTRL_HKDF_SALT = 0x1004
_EVP_PKEY_CTRL_HKDF_KEY = 0x1005
_EVP_PKEY_CTRL_HKDF_INFO = 0x1006
_EVP_PKEY_CTRL_HKDF_MODE = 0x1007

_NID_X9_62_prime256v1 = 415
_NID_secp224r1 = 713
_NID_secp384r1 = 715
_NID_secp521r1 = 716

_RSA_PKCS1_PADDING = 1
_RSA_NO_PADDING = 3
_RSA_PKCS1_OAEP_PADDING = 4
_RSA_PKCS1_PSS_PADDING = 6
_RSA_PSS_SALTLEN_DIGEST = -1
_RSA_PSS_SALTLEN_AUTO = -2
_RSA_PSS_SALTLEN_MAX_SIGN = -2
_RSA_PSS_SALTLEN_MAX = -3
_EVP_PKEY_CTRL_RSA_PADDING = 0x1001
_EVP_PKEY_CTRL_RSA_PSS_SALTLEN = 0x1002
_EVP_PKEY_CTRL_RSA_KEYGEN_BITS = 0x1003
_EVP_PKEY_CTRL_RSA_MGF1_MD = 0x1005
_EVP_PKEY_CTRL_RSA_OAEP_MD = 0x1009
_EVP_PKEY_CTRL_RSA_OAEP_LABEL = 0x100A
_EVP_PKEY_CTRL_DSA_PARAMGEN_BITS = 0x1001
_EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS = 0x1002
)
16 changes: 8 additions & 8 deletions dsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

// SupportsDSA returns true if the OpenSSL library supports DSA.
func SupportsDSA() bool {
ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_DSA, nil)
ctx := C.go_openssl_EVP_PKEY_CTX_new_id(_EVP_PKEY_DSA, nil)
if ctx == nil {
return false
}
Expand Down Expand Up @@ -66,18 +66,18 @@ func GenerateParametersDSA(l, n int) (DSAParameters, error) {
// extracting the domain parameters from it.

// Generate a new DSA key context and set the known parameters.
ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_DSA, nil)
ctx := C.go_openssl_EVP_PKEY_CTX_new_id(_EVP_PKEY_DSA, nil)
if ctx == nil {
return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_new_id failed")
}
defer C.go_openssl_EVP_PKEY_CTX_free(ctx)
if C.go_openssl_EVP_PKEY_paramgen_init(ctx) != 1 {
return DSAParameters{}, newOpenSSLError("EVP_PKEY_paramgen_init failed")
}
if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_DSA, -1, C.GO_EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, C.int(l), nil) != 1 {
if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, _EVP_PKEY_DSA, -1, _EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, C.int(l), nil) != 1 {
return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_ctrl failed")
}
if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_DSA, -1, C.GO_EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, C.int(n), nil) != 1 {
if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, _EVP_PKEY_DSA, -1, _EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, C.int(n), nil) != 1 {
return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_ctrl failed")
}
var pkey C.GO_EVP_PKEY_PTR
Expand Down Expand Up @@ -228,7 +228,7 @@ func newDSA1(params DSAParameters, x, y BigInt) (pkey C.GO_EVP_PKEY_PTR, err err
if pkey == nil {
return nil, newOpenSSLError("EVP_PKEY_new failed")
}
if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_DSA, unsafe.Pointer(dsa)) != 1 {
if C.go_openssl_EVP_PKEY_assign(pkey, _EVP_PKEY_DSA, unsafe.Pointer(dsa)) != 1 {
C.go_openssl_EVP_PKEY_free(pkey)
return nil, newOpenSSLError("EVP_PKEY_assign failed")
}
Expand All @@ -247,11 +247,11 @@ func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) {
bld.addBigInt(_OSSL_PKEY_PARAM_FFC_P, params.P, false)
bld.addBigInt(_OSSL_PKEY_PARAM_FFC_Q, params.Q, false)
bld.addBigInt(_OSSL_PKEY_PARAM_FFC_G, params.G, false)
selection := C.int(C.GO_EVP_PKEY_KEYPAIR)
selection := C.int(_EVP_PKEY_KEYPAIR)
if y != nil {
bld.addBigInt(_OSSL_PKEY_PARAM_PUB_KEY, y, false)
if x == nil {
selection = C.int(C.GO_EVP_PKEY_PUBLIC_KEY)
selection = _EVP_PKEY_PUBLIC_KEY
}
}
if x != nil {
Expand All @@ -262,7 +262,7 @@ func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) {
return nil, err
}
defer C.go_openssl_OSSL_PARAM_free(bldparams)
pkey, err := newEvpFromParams(C.GO_EVP_PKEY_DSA, selection, bldparams)
pkey, err := newEvpFromParams(_EVP_PKEY_DSA, selection, bldparams)
if err != nil {
return nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import "C"
func curveNID(curve string) C.int {
switch curve {
case "P-224":
return C.GO_NID_secp224r1
return _NID_secp224r1
case "P-256":
return C.GO_NID_X9_62_prime256v1
return _NID_X9_62_prime256v1
case "P-384":
return C.GO_NID_secp384r1
return _NID_secp384r1
case "P-521":
return C.GO_NID_secp521r1
return _NID_secp521r1
default:
panic("openssl: unknown curve " + curve)
}
Expand All @@ -39,13 +39,13 @@ func curveSize(curve string) int {
// encodeEcPoint encodes pt.
func encodeEcPoint(group C.GO_EC_GROUP_PTR, pt C.GO_EC_POINT_PTR) ([]byte, error) {
// Get encoded point size.
n := C.go_openssl_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, nil, 0, nil)
n := C.go_openssl_EC_POINT_point2oct(group, pt, _POINT_CONVERSION_UNCOMPRESSED, nil, 0, nil)
if n == 0 {
return nil, newOpenSSLError("EC_POINT_point2oct")
}
// Encode point into bytes.
bytes := make([]byte, n)
n = C.go_openssl_EC_POINT_point2oct(group, pt, C.GO_POINT_CONVERSION_UNCOMPRESSED, base(bytes), n, nil)
n = C.go_openssl_EC_POINT_point2oct(group, pt, _POINT_CONVERSION_UNCOMPRESSED, base(bytes), n, nil)
if n == 0 {
return nil, newOpenSSLError("EC_POINT_point2oct")
}
Expand Down
8 changes: 4 additions & 4 deletions ecdh.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,18 @@ func newECDHPkey3(nid C.int, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, e
}
bld.addOctetString(_OSSL_PKEY_PARAM_PUB_KEY, pubBytes)
bld.addBN(_OSSL_PKEY_PARAM_PRIV_KEY, priv)
selection = C.GO_EVP_PKEY_KEYPAIR
selection = _EVP_PKEY_KEYPAIR
} else {
bld.addOctetString(_OSSL_PKEY_PARAM_PUB_KEY, bytes)
selection = C.GO_EVP_PKEY_PUBLIC_KEY
selection = _EVP_PKEY_PUBLIC_KEY
}

params, err := bld.build()
if err != nil {
return nil, err
}
defer C.go_openssl_OSSL_PARAM_free(params)
pkey, err := newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params)
pkey, err := newEvpFromParams(_EVP_PKEY_EC, selection, params)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -261,7 +261,7 @@ func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) {
}

func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) {
pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve)
pkey, err := generateEVPPKey(_EVP_PKEY_EC, 0, curve)
if err != nil {
return nil, nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func NewPrivateKeyECDSA(curve string, x, y, d BigInt) (*PrivateKeyECDSA, error)

func GenerateKeyECDSA(curve string) (x, y, d BigInt, err error) {
// Generate the private key.
pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve)
pkey, err := generateEVPPKey(_EVP_PKEY_EC, 0, curve)
if err != nil {
return nil, nil, nil, err
}
Expand Down Expand Up @@ -195,14 +195,14 @@ func newECDSAKey3(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (C.GO_EVP_PKEY_PTR, err
var selection C.int
if bd != nil {
bld.addBN(_OSSL_PKEY_PARAM_PRIV_KEY, bd)
selection = C.GO_EVP_PKEY_KEYPAIR
selection = _EVP_PKEY_KEYPAIR
} else {
selection = C.GO_EVP_PKEY_PUBLIC_KEY
selection = _EVP_PKEY_PUBLIC_KEY
}
params, err := bld.build()
if err != nil {
return nil, err
}
defer C.go_openssl_OSSL_PARAM_free(params)
return newEvpFromParams(C.GO_EVP_PKEY_EC, selection, params)
return newEvpFromParams(_EVP_PKEY_EC, selection, params)
}
8 changes: 4 additions & 4 deletions ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var supportsEd25519 = sync.OnceValue(func() bool {
switch vMajor {
case 1:
if versionAtOrAbove(1, 1, 1) {
ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_ED25519, nil)
ctx := C.go_openssl_EVP_PKEY_CTX_new_id(_EVP_PKEY_ED25519, nil)
if ctx != nil {
C.go_openssl_EVP_PKEY_CTX_free(ctx)
return true
Expand Down Expand Up @@ -99,7 +99,7 @@ func (k *PrivateKeyEd25519) Public() (*PublicKeyEd25519, error) {

// GenerateKeyEd25519 generates a private key.
func GenerateKeyEd25519() (*PrivateKeyEd25519, error) {
pkeyPriv, err := generateEVPPKey(C.GO_EVP_PKEY_ED25519, 0, "")
pkeyPriv, err := generateEVPPKey(_EVP_PKEY_ED25519, 0, "")
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -129,7 +129,7 @@ func NewPublicKeyEd25519(pub []byte) (*PublicKeyEd25519, error) {
if len(pub) != publicKeySizeEd25519 {
panic("ed25519: bad public key length: " + strconv.Itoa(len(pub)))
}
pkey := C.go_openssl_EVP_PKEY_new_raw_public_key(C.GO_EVP_PKEY_ED25519, nil, base(pub), C.size_t(len(pub)))
pkey := C.go_openssl_EVP_PKEY_new_raw_public_key(_EVP_PKEY_ED25519, nil, base(pub), C.size_t(len(pub)))
if pkey == nil {
return nil, newOpenSSLError("EVP_PKEY_new_raw_public_key")
}
Expand All @@ -145,7 +145,7 @@ func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) {
if len(seed) != seedSizeEd25519 {
panic("ed25519: bad seed length: " + strconv.Itoa(len(seed)))
}
pkey := C.go_openssl_EVP_PKEY_new_raw_private_key(C.GO_EVP_PKEY_ED25519, nil, base(seed), C.size_t(len(seed)))
pkey := C.go_openssl_EVP_PKEY_new_raw_private_key(_EVP_PKEY_ED25519, nil, base(seed), C.size_t(len(seed)))
if pkey == nil {
return nil, newOpenSSLError("EVP_PKEY_new_raw_private_key")
}
Expand Down
Loading
Loading