From 6ec9cf04d285ab2d28273ae04832c8bf144accc4 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Fri, 29 Nov 2024 08:00:51 +0100 Subject: [PATCH 01/20] generate PKEYs using EVP_PKEY_Q_keygen --- cmd/checkheader/main.go | 4 +++ ed25519.go | 5 +-- evp.go | 69 +++++++++++++++++++++++++++++------------ goopenssl.c | 8 +++++ goopenssl.h | 3 ++ shims.h | 9 ++++++ 6 files changed, 75 insertions(+), 23 deletions(-) diff --git a/cmd/checkheader/main.go b/cmd/checkheader/main.go index 28cb1217..94d841bd 100644 --- a/cmd/checkheader/main.go +++ b/cmd/checkheader/main.go @@ -227,6 +227,10 @@ func tryConvertDefineFunc(w io.Writer, l string, i int) bool { if !strings.HasPrefix(l, "DEFINEFUNC") { return false } + if strings.HasPrefix(l, "DEFINEFUNC_VARIADIC") { + // Variadic functions are not supported. + return false + } i1 := strings.IndexByte(l, '(') // The first ")," match is always the end of the argument list parameter. // We are not interested in the last parameter and parsing them would complicate the algorithm. diff --git a/ed25519.go b/ed25519.go index 77ccbf59..cd237025 100644 --- a/ed25519.go +++ b/ed25519.go @@ -9,7 +9,6 @@ import ( "runtime" "strconv" "sync" - "unsafe" ) const ( @@ -37,9 +36,7 @@ var supportsEd25519 = sync.OnceValue(func() bool { } } case 3: - name := C.CString("ED25519") - defer C.free(unsafe.Pointer(name)) - sig := C.go_openssl_EVP_SIGNATURE_fetch(nil, name, nil) + sig := C.go_openssl_EVP_SIGNATURE_fetch(nil, keyTypeED25519, nil) if sig != nil { C.go_openssl_EVP_SIGNATURE_free(sig) return true diff --git a/evp.go b/evp.go index 91296a93..73f65c7c 100644 --- a/evp.go +++ b/evp.go @@ -13,6 +13,12 @@ import ( "unsafe" ) +var ( + keyTypeRSA = C.CString("RSA") + keyTypeEC = C.CString("EC") + keyTypeED25519 = C.CString("ED25519") +) + // cacheMD is a cache of crypto.Hash to GO_EVP_MD_PTR. var cacheMD sync.Map @@ -157,36 +163,61 @@ func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { return nil } +// generateEVPPKey generates a new EVP_PKEY with the given id and properties. func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error) { if bits != 0 && curve != "" { return nil, fail("incorrect generateEVPPKey parameters") } - ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new_id failed") - } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { - return nil, newOpenSSLError("EVP_PKEY_keygen_init failed") - } - if bits != 0 { - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS, C.int(bits), nil) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") - } - } + var curveID C.int if curve != "" { - nid, err := curveNID(curve) + var err error + curveID, err = curveNID(curve) if err != nil { return nil, err } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, nil) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") - } } var pkey C.GO_EVP_PKEY_PTR - if C.go_openssl_EVP_PKEY_keygen(ctx, &pkey) != 1 { - return nil, newOpenSSLError("EVP_PKEY_keygen failed") + switch vMajor { + case 1: + ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) + if ctx == nil { + return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") + } + defer C.go_openssl_EVP_PKEY_CTX_free(ctx) + if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { + return nil, newOpenSSLError("EVP_PKEY_keygen_init") + } + if bits != 0 { + if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS, C.int(bits), nil) != 1 { + return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl") + } + } + if curve != "" { + if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, curveID, nil) != 1 { + return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl") + } + } + if C.go_openssl_EVP_PKEY_keygen(ctx, &pkey) != 1 { + return nil, newOpenSSLError("EVP_PKEY_keygen") + } + case 3: + switch id { + case C.GO_EVP_PKEY_RSA: + pkey = C.go_openssl_EVP_PKEY_Q_keygen_RSA(nil, nil, keyTypeRSA, C.size_t(bits)) + case C.GO_EVP_PKEY_EC: + pkey = C.go_openssl_EVP_PKEY_Q_keygen_EC(nil, nil, keyTypeEC, C.go_openssl_OBJ_nid2sn(curveID)) + case C.GO_EVP_PKEY_ED25519: + pkey = C.go_openssl_EVP_PKEY_Q_keygen(nil, nil, keyTypeED25519) + default: + panic("unsupported key type '" + strconv.Itoa(int(id)) + "'") + } + if pkey == nil { + return nil, newOpenSSLError("EVP_PKEY_Q_keygen") + } + default: + panic(errUnsupportedVersion()) } + return pkey, nil } diff --git a/goopenssl.c b/goopenssl.c index c3385b9d..626f184b 100644 --- a/goopenssl.c +++ b/goopenssl.c @@ -22,6 +22,7 @@ #define DEFINEFUNC_3_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) #define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) #define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) +#define DEFINEFUNC_VARIADIC_3_0(ret, func, newname, args, argscall) DEFINEFUNC(ret, newname, args, argscall) FOR_ALL_OPENSSL_FUNCTIONS @@ -34,6 +35,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #undef DEFINEFUNC_3_0 #undef DEFINEFUNC_RENAMED_1_1 #undef DEFINEFUNC_RENAMED_3_0 +#undef DEFINEFUNC_VARIADIC_3_0 // go_openssl_fips_enabled returns 1 if FIPS mode is enabled, 0 otherwise. // As a special case, it returns -1 if it cannot determine if FIPS mode is enabled. @@ -140,6 +142,11 @@ go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, { \ DEFINEFUNC_INTERNAL(func, #func) \ } +#define DEFINEFUNC_VARIADIC_3_0(ret, func, newname, args, argscall) \ + if (major == 3) \ + { \ + DEFINEFUNC_INTERNAL(newname, #func) \ + } FOR_ALL_OPENSSL_FUNCTIONS @@ -152,6 +159,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #undef DEFINEFUNC_3_0 #undef DEFINEFUNC_RENAMED_1_1 #undef DEFINEFUNC_RENAMED_3_0 +#undef DEFINEFUNC_VARIADIC_3_0 } static unsigned long diff --git a/goopenssl.h b/goopenssl.h index a50caa3d..1165f991 100644 --- a/goopenssl.h +++ b/goopenssl.h @@ -59,6 +59,8 @@ int go_openssl_DSA_set0_key_backport(GO_DSA_PTR d, GO_BIGNUM_PTR pub_key, GO_BIG DEFINEFUNC(ret, func, args, argscall) #define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ DEFINEFUNC(ret, func, args, argscall) +#define DEFINEFUNC_VARIADIC_3_0(ret, func, newname, args, argscall) \ + DEFINEFUNC(ret, newname, args, argscall) FOR_ALL_OPENSSL_FUNCTIONS @@ -71,6 +73,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #undef DEFINEFUNC_3_0 #undef DEFINEFUNC_RENAMED_1_1 #undef DEFINEFUNC_RENAMED_3_0 +#undef DEFINEFUNC_VARIADIC_3_0 // go_hash_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. // This is necessary because Go hash.Hash mandates that Sum has no effect diff --git a/shims.h b/shims.h index 156d8e8a..7d2e0a49 100644 --- a/shims.h +++ b/shims.h @@ -157,6 +157,12 @@ typedef void* GO_SHA_CTX_PTR; // DEFINEFUNC_RENAMED_3_0 acts like DEFINEFUNC but tries to load the function using the new name when using >= 3.x // and the old name when using 1.x. In both cases the function will have the new name. // +// DEFINEFUNC_VARIADIC_3_0 defines a function that wraps an OpenSSL function with a different name and signature. +// It should only be used for functions that can't be directly called from Go because their signature is not +// compatible with cgo. The only known case are functions that take a variable number of arguments. See +// https://github.com/golang/go/issues/975. +// The process is aborted if the function can't be loaded when using 3.0.0 or higher. +// // #include // #include // #include @@ -298,6 +304,9 @@ DEFINEFUNC(int, EVP_PKEY_paramgen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ DEFINEFUNC(int, EVP_PKEY_paramgen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ DEFINEFUNC(int, EVP_PKEY_keygen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ DEFINEFUNC(int, EVP_PKEY_keygen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ +DEFINEFUNC_VARIADIC_3_0(GO_EVP_PKEY_PTR, EVP_PKEY_Q_keygen, EVP_PKEY_Q_keygen, (GO_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type), (ctx, propq, type)) \ +DEFINEFUNC_VARIADIC_3_0(GO_EVP_PKEY_PTR, EVP_PKEY_Q_keygen, EVP_PKEY_Q_keygen_RSA, (GO_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type, size_t arg1), (ctx, propq, type, arg1)) \ +DEFINEFUNC_VARIADIC_3_0(GO_EVP_PKEY_PTR, EVP_PKEY_Q_keygen, EVP_PKEY_Q_keygen_EC, (GO_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type, const char *arg1), (ctx, propq, type, arg1)) \ DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ DEFINEFUNC(int, EVP_PKEY_CTX_ctrl, (GO_EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2), (ctx, keytype, optype, cmd, p1, p2)) \ DEFINEFUNC(int, EVP_PKEY_decrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ From 13b7c8bc2c8ad0490011f59a9c27514a3b771414 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 11:54:49 +0100 Subject: [PATCH 02/20] implement mkcgo --- internal/mkcgo/generate.go | 355 +++++++++++++++++++++++++++++++++++++ internal/mkcgo/mkcgo.go | 139 +++++++++++++++ internal/mkcgo/parse.go | 243 +++++++++++++++++++++++++ 3 files changed, 737 insertions(+) create mode 100644 internal/mkcgo/generate.go create mode 100644 internal/mkcgo/mkcgo.go create mode 100644 internal/mkcgo/parse.go diff --git a/internal/mkcgo/generate.go b/internal/mkcgo/generate.go new file mode 100644 index 00000000..3030d813 --- /dev/null +++ b/internal/mkcgo/generate.go @@ -0,0 +1,355 @@ +package main + +import ( + "fmt" + "io" + "slices" + "strconv" + "strings" +) + +// Generate output source file from a source set src. +func (src *source) generate(w io.Writer) { + fmt.Fprintf(w, "// Code generated by mkcgo. DO NOT EDIT.\n\n") + fmt.Fprintf(w, "package %s\n\n", *packageName) + fmt.Fprintf(w, "/*\n") + if *includeHeader != "" { + fmt.Fprintf(w, "#include \"%s\"\n", *includeHeader) + } + for _, file := range src.files { + fmt.Fprintf(w, "#include %q\n", file) + } + fmt.Fprintf(w, "void __mkcgoLoad_%s(void* handle);\n", *libName) + fmt.Fprintf(w, "*/\n") + fmt.Fprintf(w, "import \"C\"\n") + if len(src.stdLibImports) > 0 { + fmt.Fprintf(w, "import (\n") + for _, imp := range src.stdLibImports { + fmt.Fprintf(w, "\t%q\n", imp) + } + fmt.Fprintf(w, ")\n\n") + } + + fmt.Fprintf(w, "func mkcgoLoad_%s(handle unsafe.Pointer) {\n", *libName) + fmt.Fprintf(w, "\tC.__mkcgoLoad_%s(handle)\n", *libName) + fmt.Fprintf(w, "}\n\n") + + for _, fn := range src.funcs { + if fn.cOnly { + continue + } + fn.generate(w) + } +} + +func (src *source) generateC(w io.Writer) { + fmt.Fprintf(w, "// Code generated by mkcgo. DO NOT EDIT.\n\n") + if *includeHeader != "" { + fmt.Fprintf(w, "#include \"%s\"\n", *includeHeader) + } + fmt.Fprintf(w, "#include \n") + fmt.Fprintf(w, "#include \n") + fmt.Fprintf(w, "#include \n") + fmt.Fprintf(w, "\n") + + fmt.Fprintf(w, "#ifdef _WIN32\n") + fmt.Fprintf(w, "#include \n") + fmt.Fprintf(w, "#define dlsym GetProcAddress\n") + fmt.Fprintf(w, "#else\n") + fmt.Fprintf(w, "#include \n") + fmt.Fprintf(w, "#endif\n\n") + + for _, fn := range src.funcs { + if fn.isVariadic { + continue + } + fmt.Fprintf(w, "%s (*_g_%s)(%s);\n", fn.rets.typ, fn.libName, fn.libArgList(false, true)) + } + fmt.Fprintf(w, "\n") + + fmt.Fprintf(w, "void __mkcgoLoad_%s(void* handle) {\n", *libName) + for _, fn := range src.funcs { + if fn.isVariadic { + continue + } + fmt.Fprintf(w, "\t_g_%s = (%s (*)(%s))dlsym(handle, %q);\n", fn.libName, fn.rets.typ, fn.libArgList(false, true), fn.importName) + } + fmt.Fprintf(w, "}\n\n") + + for _, fn := range src.funcs { + if fn.isVariadic { + continue + } + fmt.Fprintf(w, "%s %s(%s) {\n", fn.rets.typ, fn.libName, fn.libArgList(true, true)) + fmt.Fprintf(w, "\t") + if fn.rets.typ != "void" { + fmt.Fprintf(w, "return ") + } + fmt.Fprintf(w, "_g_%s(%s);\n", fn.libName, fn.libArgList(true, false)) + fmt.Fprintf(w, "}\n\n") + } +} + +func (f *fn) generate(w io.Writer) { + fmt.Fprintf(w, "func %s(%s)", f.name, f.paramList()) + ret := f.rets.list() + if len(ret) > 0 { + fmt.Fprintf(w, " %s ", ret) + } + fmt.Fprintf(w, "{\n") + fmt.Fprintf(w, "\t") + if !f.rets.isVoid() { + fmt.Fprintf(w, "r0 := ") + } + fmt.Fprintf(w, "C.%s(%s)\n", f.libName, f.argList()) + if !f.rets.isVoid() { + errSrc := f.rets.errorSrc(f.libName) + if len(errSrc) > 0 { + fmt.Fprintf(w, "\t%s\n", errSrc) + } + fmt.Fprintf(w, "\treturn\n") + } + fmt.Fprintf(w, "}\n\n") +} + +// argList returns source code fragments representing p parameter in a C call. +// Slices are translated into 2 syscall parameters: pointer to the first element and length. +func (p *param) argList() []string { + goType := cArgToGo(p.typ) + var s string + switch { + case goType == "": + return []string{""} + case goType == "unsafe.Pointer": + return []string{p.name} + case goType[0] == '*': + return []string{fmt.Sprintf("(%s)(unsafe.Pointer(%s))", goType, p.name)} + default: + s = p.name + } + return []string{fmt.Sprintf("%s(%s)", goType, s)} +} + +func cArgToGo(t string) string { + t, _ = strings.CutPrefix(t, "const ") + if t == "void" { + return "" + } + if strings.Contains(t, "void*") { + return "unsafe.Pointer" + } + if strings.HasSuffix(t, "*") { + // Remove all trailing '*' characters. + var i, n int + for i = len(t) - 1; i >= 0; i-- { + if t[i] != '*' { + break + } + n++ + } + s := cArgToGo(t[:i+1]) + s = strings.Repeat("*", n) + s + return s + } + // Map C types with spaces to cgo special-cased types. + switch t { + case "signed char": + t = "schar" + case "unsigned char": + t = "uchar" + case "unsigned short": + t = "ushort" + case "unsigned int": + t = "uint" + case "unsigned long": + t = "ulong" + case "long long": + t = "longlong" + case "unsigned long long": + t = "ulonglong" + } + return "C." + t +} + +func cTypeToGo(t string) string { + t, _ = strings.CutPrefix(t, "const ") + if t == "void" { + return "" + } + if strings.HasSuffix(t, "void*") { + return "unsafe.Pointer" + } + if strings.HasSuffix(t, "*") { + // Remove all trailing '*' characters. + var i, n int + for i = len(t) - 1; i >= 0; i-- { + if t[i] != '*' { + break + } + n++ + } + s := cTypeToGo(t[:i+1]) + s = strings.Repeat("*", n) + s + return s + } + var s string + switch t { + case "int8_t": + s = "int8" + case "uint8_t": + s = "uint8" + case "int16_t": + s = "int16" + case "uint16_t": + s = "uint16" + case "int32_t": + s = "int32" + case "uint32_t": + s = "uint32" + case "int64_t": + s = "int64" + case "uint64_t": + s = "uint64" + case "int": + s = "int32" + case "unsigned int": + s = "uint32" + case "long": + s = "int64" + case "unsigned long": + s = "uint64" + case "size_t": + s = "int" + case "uintptr_t": + s = "uintptr" + case "char", "unsigned char": + s = "byte" + default: + s = strings.ToUpper(t[:1]) + t[1:] + } + return s +} + +func (p *param) libArgList(paramNames, paramTypes bool) []string { + var s string + if paramTypes { + s += p.typ + } + if paramNames && p.typ != "void" { + if len(s) > 0 { + s += " " + } + s += "_arg" + strconv.Itoa(p.tmpVarIdx) + } + return []string{s} +} + +// toParams converts r into slice of *Param. +func (r *rets) toParams() []*param { + ps := make([]*param, 0, 2) + if len(r.name) > 0 && !r.isVoid() && !r.errorOnly { + ps = append(ps, ¶m{name: r.name, typ: cTypeToGo(r.typ), tmpVarIdx: len(ps)}) + } + if r.returnsError { + ps = append(ps, ¶m{name: "err", typ: "error", tmpVarIdx: len(ps)}) + } + return ps +} + +// list returns source code of syscall return parameters. +func (r *rets) list() string { + s := join(r.toParams(), func(p *param) string { return p.name + " " + p.typ }, ", ") + if len(s) > 0 { + s = "(" + s + ")" + } else if r.fnMaybeAbsent { + s = "(err error)" + } + return s +} + +func (r *rets) useLongHandleErrorCode(retvar, msg string) string { + const code = `if %s { + err = newError(%q) + }` + var cond string + if strings.HasSuffix(r.typ, "*") || strings.HasSuffix(strings.ToUpper(r.typ), "_PTR") { + cond = retvar + " == nil" + } else { + cond = retvar + " != " + defaultErrorCodeStr + cond = strings.Replace(r.failCond, "retval", retvar, 1) + } + return fmt.Sprintf(code, cond, msg) +} + +func (r *rets) isVoid() bool { + return r.typ == "void" +} + +// errorSrc returns source code that sets return parameters. +func (r *rets) errorSrc(fnName string) string { + if r.isVoid() { + return "" + } + if r.name == "" || r.errorOnly { + return r.useLongHandleErrorCode("r0", fnName) + } + goType := cTypeToGo(r.typ) + s := "" + switch { + case goType[0] == '*': + s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.name, goType) + default: + s = fmt.Sprintf("%s = %s(r0)", r.name, goType) + } + if !r.returnsError { + return s + } + return s + "\n\t" + r.useLongHandleErrorCode(r.name, fnName) +} + +// paramList returns source code for function f parameters. +func (f *fn) paramList() string { + return join(f.params, func(p *param) string { return p.name + " " + cTypeToGo(p.typ) }, ", ") +} + +func syscalldot() string { + return "syscall." +} + +// argList returns source code for C parameters for function f. +func (f *fn) argList() string { + a := make([]string, 0, len(f.params)) + for _, p := range f.params { + a = append(a, p.argList()...) + } + a = slices.DeleteFunc(a, func(s string) bool { + return s == "" + }) + return strings.Join(a, ", ") +} + +// libArgList returns source code for C parameters for function f. +func (f *fn) libArgList(paramNames, paramTypes bool) string { + a := make([]string, 0, len(f.params)) + for _, p := range f.params { + a = append(a, p.libArgList(paramNames, paramTypes)...) + } + a = slices.DeleteFunc(a, func(s string) bool { + return s == "" + }) + return strings.Join(a, ", ") +} + +// join concatenates parameters ps into a string with sep separator. +// Each parameter is converted into string by applying fn to it +// before conversion. +func join(ps []*param, fn func(*param) string, sep string) string { + if len(ps) == 0 { + return "" + } + a := make([]string, 0, len(ps)) + for _, p := range ps { + a = append(a, fn(p)) + } + return strings.Join(a, sep) +} diff --git a/internal/mkcgo/mkcgo.go b/internal/mkcgo/mkcgo.go new file mode 100644 index 00000000..8d91cbd2 --- /dev/null +++ b/internal/mkcgo/mkcgo.go @@ -0,0 +1,139 @@ +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "log" + "os" + "strings" +) + +var ( + defaultErrorCodeStr string +) + +var ( + fileName = flag.String("out", "", "output file name (standard output if omitted)") + includeHeader = flag.String("include", "", "include header file") + packageName = flag.String("package", "", "package name") + libName = flag.String("lib", "", "library name") +) + +func usage() { + fmt.Fprintf(os.Stderr, "usage: mkcgo [flags] [path ...]\n") + flag.PrintDefaults() + os.Exit(1) +} + +func main() { + flag.Usage = usage + flag.Parse() + if len(flag.Args()) <= 0 { + fmt.Fprintf(os.Stderr, "no files to parse provided\n") + usage() + } + + src, err := parseFiles(flag.Args()) + if err != nil { + log.Fatal(err) + } + + var buf, cbuf bytes.Buffer + src.generate(&buf) + src.generateC(&cbuf) + + data, err := format.Source(buf.Bytes()) + if err != nil { + log.Printf("failed to format source: %v", err) + f, err := writeTempSourceFile(buf.Bytes()) + if err != nil { + log.Fatalf("failed to write unformatted source to file: %v", err) + } + log.Fatalf("for diagnosis, wrote unformatted source to %v", f) + } + if *fileName == "" { + _, err = os.Stdout.Write(data) + if err == nil { + _, err = os.Stdout.Write(cbuf.Bytes()) + } + } else { + err = os.WriteFile(*fileName, data, 0644) + if err == nil { + cfileName := strings.TrimSuffix(*fileName, ".go") + ".c" + err = os.WriteFile(cfileName, cbuf.Bytes(), 0644) + } + } + if err != nil { + log.Fatal(err) + } +} + +// param is function parameter. +type param struct { + name string + typ string + tmpVarIdx int +} + +// isError determines if p parameter is used to return error. +func (p *param) isError() bool { + return p.name == "err" && p.typ == "error" +} + +// rets is function return values. +type rets struct { + name string + typ string + returnsError bool + errorOnly bool + failCond string + errorType string + fnMaybeAbsent bool +} + +type fnOptions struct { + name string + libName string + errorType string + errorOnly bool + returnsError bool + failCondition string + importName string + cOnly bool +} + +// fn describes a function. +type fn struct { + name string + libName string + importName string + params []*param + rets *rets + src string + isVariadic bool + cOnly bool +} + +type source struct { + funcs []*fn + stdLibImports []string + files []string +} + +func writeTempSourceFile(data []byte) (string, error) { + f, err := os.CreateTemp("", "mkcgo-generated-*.go") + if err != nil { + return "", err + } + _, err = f.Write(data) + if closeErr := f.Close(); err == nil { + err = closeErr + } + if err != nil { + os.Remove(f.Name()) // best effort + return "", err + } + return f.Name(), nil +} diff --git a/internal/mkcgo/parse.go b/internal/mkcgo/parse.go new file mode 100644 index 00000000..eb46d1eb --- /dev/null +++ b/internal/mkcgo/parse.go @@ -0,0 +1,243 @@ +package main + +import ( + "bufio" + "cmp" + "errors" + "os" + "slices" + "strings" +) + +// parseFiles parses files listed in fs and extracts all syscall +// functions listed in sys comments. It returns source files +// and functions collection *Source if successful. +func parseFiles(fs []string) (*source, error) { + src := &source{ + funcs: make([]*fn, 0), + stdLibImports: []string{ + "unsafe", + }, + files: fs, + } + for _, file := range fs { + if err := src.parseFile(file); err != nil { + return nil, err + } + } + return src, nil +} + +func (src *source) parseFile(name string) error { + file, err := os.Open(name) + if err != nil { + return err + } + defer file.Close() + s := bufio.NewScanner(file) + var inComment bool + var srcOps, fnOps fnOptions + var t string + for s.Scan() { + line := trim(s.Text()) + if strings.HasPrefix(line, "/*") { + if !strings.HasSuffix(line, "*/") { + inComment = true + } + continue + } + if inComment && strings.HasSuffix(line, "*/") { + inComment = false + continue + } + if inComment { + continue + } + if t, ok := strings.CutPrefix(line, "//mkcgo:"); ok { + if v, ok := strings.CutPrefix(t, "failCondition "); ok { + srcOps.failCondition = v + fnOps.failCondition = v + continue + } + return errors.New("Unknown mkcgo directive: " + t) + } + + if strings.HasPrefix(line, "[[") { + for { + var body string + var ok bool + _, body, line, ok = extractSection(line, "[[", "]]") + if !ok { + break + } + body, ok = strings.CutPrefix(body, "mkcgo::") + if !ok { + continue + } + if body == "error" { + fnOps.returnsError = true + } else if body == "error_only" { + fnOps.returnsError = true + fnOps.errorOnly = true + } else if body == "c_only" { + fnOps.cOnly = true + } else if strings.HasPrefix(body, "error(") || strings.HasPrefix(body, "error_only(") { + fnOps.returnsError = true + fnOps.errorOnly = strings.HasPrefix(body, "error_only(") + if _, body, _, ok = extractSection(body, "(", ")"); ok { + fnOps.failCondition = strings.Trim(body, `"`) + } + } else if strings.HasPrefix(body, "name(") { + if _, body, _, ok = extractSection(body, "(", ")"); ok { + fnOps.name = strings.Trim(body, `"`) + } + } else if strings.HasPrefix(body, "variadic(") { + if _, body, _, ok = extractSection(body, "(", ")"); ok { + fnOps.importName = strings.Trim(body, `"`) + } + } + } + } + + if strings.HasPrefix(line, "//") || strings.HasPrefix(line, "#") { + continue + } + if line == "" { + continue + } + if t != "" { + t += " " + } + t += line + if !strings.HasSuffix(line, ";") { + // Accept multiline lines + continue + } + f, err := newFn(t, fnOps) + if err != nil { + return err + } + src.funcs = append(src.funcs, f) + fnOps = fnOptions{ + errorType: srcOps.errorType, + failCondition: srcOps.failCondition, + } + t = "" + } + if err := s.Err(); err != nil { + return err + } + slices.SortFunc(src.funcs, func(fi, fj *fn) int { + return cmp.Compare(fi.libName, fj.libName) + }) + return nil +} + +// newFn parses string s and return created function Fn. +func newFn(s string, opts fnOptions) (*fn, error) { + f := &fn{ + rets: &rets{}, + src: s, + } + // function name and args + prefix, body, s, found := extractSection(s, "(", ")") + if !found || prefix == "" { + return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"") + } + var err error + f.params, err = extractParams(body) + if err != nil { + return nil, err + } + nameIdx := strings.LastIndexByte(prefix, ' ') + if nameIdx < 0 || nameIdx+1 >= len(prefix) { + return nil, errors.New("Could not extract function name from \"" + f.src + "\"") + } + name, typ := trim(prefix[nameIdx+1:]), trim(prefix[:nameIdx]) + for strings.HasPrefix(name, "*") { + name = name[1:] + typ += "*" + } + f.libName = trim(name) + if opts.importName != "" { + f.importName = opts.importName + } else { + f.importName = f.libName + } + if opts.name != "" { + f.name = opts.name + } else { + f.name = f.libName + } + f.cOnly = opts.cOnly + f.rets = &rets{ + typ: trim(typ), + name: "_r0", + returnsError: opts.returnsError, + errorOnly: opts.errorOnly, + failCond: opts.failCondition, + } + return f, nil +} + +// trim returns s with leading and trailing spaces and tabs removed. +func trim(s string) string { + return strings.Trim(s, " \t") +} + +// extractSection extracts text out of string s starting after start +// and ending just before end. found return value will indicate success, +// and prefix, body and suffix will contain correspondent parts of string s. +func extractSection(s string, start, end string) (prefix, body, suffix string, found bool) { + s = trim(s) + if v, ok := strings.CutPrefix(s, start); ok { + // no prefix + body = v + } else { + a := strings.SplitN(s, start, 2) + if len(a) != 2 { + return "", "", s, false + } + prefix = a[0] + body = a[1][len(start)-1:] + } + a := strings.SplitN(body, end, 2) + if len(a) != 2 { + return "", "", "", false + } + return prefix, a[0], a[1], true +} + +// extractParams parses s to extract function parameters. +func extractParams(s string) ([]*param, error) { + s = trim(s) + if s == "" { + return nil, nil + } + a := strings.Split(s, ",") + ps := make([]*param, 0, len(a)) + for i := range a { + s2 := trim(a[i]) + if i == len(a)-1 && s2 == "..." { + break // omit variadic argument + } + b := strings.LastIndexByte(s2, ' ') + var name, typ string + if b != -1 { + name, typ = trim(s2[b+1:]), trim(s2[:b]) + } else { + typ = trim(s2) + } + for strings.HasPrefix(name, "*") { + name = name[1:] + typ += "*" + } + name = trim(name) + ps = append(ps, ¶m{ + name: name, + typ: typ, + tmpVarIdx: i, + }) + } + return ps, nil +} From d14ed270b5b5e1874ea174b4087c1f26335fc27a Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 11:56:52 +0100 Subject: [PATCH 03/20] generate wrappers --- internal/ossl/api.h | 268 ++++++ internal/ossl/const.go | 127 +++ internal/ossl/ossl.go | 5 + internal/ossl/ossl.h | 50 ++ internal/ossl/ossl_cgo.go | 36 + internal/ossl/zossl.c | 1404 ++++++++++++++++++++++++++++++++ internal/ossl/zossl.go | 1629 +++++++++++++++++++++++++++++++++++++ 7 files changed, 3519 insertions(+) create mode 100644 internal/ossl/api.h create mode 100644 internal/ossl/const.go create mode 100644 internal/ossl/ossl.go create mode 100644 internal/ossl/ossl.h create mode 100644 internal/ossl/ossl_cgo.go create mode 100644 internal/ossl/zossl.c create mode 100644 internal/ossl/zossl.go diff --git a/internal/ossl/api.h b/internal/ossl/api.h new file mode 100644 index 00000000..e96919a0 --- /dev/null +++ b/internal/ossl/api.h @@ -0,0 +1,268 @@ +//mkcgo:failCondition retval != 1 + +#include "ossl.h" +#include + +void ERR_clear_error(void); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_all(const char **file, int *line, + const char **fn, + const char **data, int *flags); +void ERR_load_crypto_strings(void); +[[mkcgo::c_only]] void ERR_remove_thread_state(const CRYPTO_THREADID_PTR tid); + +[[mkcgo::c_only]] int CRYPTO_num_locks(void); +[[mkcgo::c_only]] int CRYPTO_THREADID_set_callback(threadid_func fn); +[[mkcgo::c_only]] void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID_PTR id, unsigned long val); +[[mkcgo::c_only]] void CRYPTO_set_locking_callback(locking_func fn); + +[[mkcgo::name("_SSLeay_version")]] const char *SSLeay_version(int typ); +[[mkcgo::name("_OpenSSL_version")]] const char *OpenSSL_version(int typ); +void OPENSSL_init(void); +void OPENSSL_add_all_algorithms_conf(void); +[[mkcgo::error_only]] int OPENSSL_init_crypto(uint64_t ops, const OPENSSL_INIT_SETTINGS_PTR settings); + +void *CRYPTO_malloc(size_t num, const char *file, int line); +void CRYPTO_free(void *str, const char *file, int line); + +int FIPS_mode(void); +[[mkcgo::error_only]] int FIPS_mode_set(int r); + +int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX_PTR libctx); +[[mkcgo::error_only]] int EVP_default_properties_enable_fips(OSSL_LIB_CTX_PTR libctx, int enable); + +[[mkcgo::error_only]] int RAND_bytes(unsigned char *buf, int num); + +EVP_CIPHER_PTR EVP_aes_128_gcm(void); +EVP_CIPHER_PTR EVP_aes_192_gcm(void); +EVP_CIPHER_PTR EVP_aes_256_gcm(void); +EVP_CIPHER_PTR EVP_aes_128_cbc(void); +EVP_CIPHER_PTR EVP_aes_192_cbc(void); +EVP_CIPHER_PTR EVP_aes_256_cbc(void); +EVP_CIPHER_PTR EVP_aes_128_ctr(void); +EVP_CIPHER_PTR EVP_aes_192_ctr(void); +EVP_CIPHER_PTR EVP_aes_256_ctr(void); +EVP_CIPHER_PTR EVP_aes_128_ecb(void); +EVP_CIPHER_PTR EVP_aes_192_ecb(void); +EVP_CIPHER_PTR EVP_aes_256_ecb(void); +EVP_CIPHER_PTR EVP_des_cbc(void); +EVP_CIPHER_PTR EVP_des_ecb(void); +EVP_CIPHER_PTR EVP_des_ede3_cbc(void); +EVP_CIPHER_PTR EVP_des_ede3_ecb(void); +EVP_CIPHER_PTR EVP_rc4(void); + +[[mkcgo::error]] EVP_CIPHER_PTR EVP_CIPHER_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +[[mkcgo::error]] EVP_CIPHER_CTX_PTR EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX_PTR ctx); +[[mkcgo::error_only]] int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX_PTR ctx, int cmd, int p1, void *p2); +[[mkcgo::error_only]] int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX_PTR x, int padding); +[[mkcgo::name("_EVP_CIPHER_block_size")]] int EVP_CIPHER_block_size(const EVP_CIPHER_PTR e); +[[mkcgo::name("_EVP_CIPHER_get_block_size")]] int EVP_CIPHER_get_block_size(const EVP_CIPHER_PTR e); +const char *EVP_CIPHER_get0_name(const EVP_CIPHER_PTR cipher); +[[mkcgo::error_only]] int EVP_CipherInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv, int enc); +[[mkcgo::error_only]] int EVP_CipherUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +[[mkcgo::error_only]] int EVP_EncryptInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv); +[[mkcgo::error_only]] int EVP_EncryptUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +[[mkcgo::error_only]] int EVP_EncryptFinal_ex(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl); +[[mkcgo::error_only]] int EVP_DecryptInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv); +[[mkcgo::error_only]] int EVP_DecryptUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +[[mkcgo::error_only]] int EVP_DecryptFinal_ex(EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl); +[[mkcgo::error_only]] int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX_PTR ctx, int keylen); + +void EVP_PKEY_free(EVP_PKEY_PTR key); +[[mkcgo::name("_EVP_PKEY_size")]] int EVP_PKEY_size(const EVP_PKEY_PTR pkey); +[[mkcgo::name("_EVP_PKEY_get_size")]] int EVP_PKEY_get_size(const EVP_PKEY_PTR pkey); +[[mkcgo::name("_EVP_PKEY_bits")]] int EVP_PKEY_bits(const EVP_PKEY_PTR pkey); +[[mkcgo::name("_EVP_PKEY_get_bits")]] int EVP_PKEY_get_bits(const EVP_PKEY_PTR pkey); +[[mkcgo::error]] EVP_PKEY_PTR EVP_PKEY_new(void); +[[mkcgo::error]] EVP_PKEY_PTR EVP_PKEY_new_raw_private_key(int typ, ENGINE_PTR e, const unsigned char *key, size_t keylen); +[[mkcgo::error]] EVP_PKEY_PTR EVP_PKEY_new_raw_public_key(int typ, ENGINE_PTR e, const unsigned char *key, size_t keylen); +[[mkcgo::error("retval == 0")]] size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY_PTR pkey, unsigned char **ppub); +[[mkcgo::error]] RSA_PTR EVP_PKEY_get1_RSA(EVP_PKEY_PTR pkey); +[[mkcgo::error]] const DSA_PTR EVP_PKEY_get0_DSA(const EVP_PKEY_PTR pkey); +[[mkcgo::error]] const EC_KEY_PTR EVP_PKEY_get0_EC_KEY(const EVP_PKEY_PTR pkey); +[[mkcgo::error]] void *EVP_PKEY_get0(const EVP_PKEY_PTR pkey); +[[mkcgo::error_only]] int EVP_PKEY_up_ref(EVP_PKEY_PTR key); +[[mkcgo::error_only]] int EVP_PKEY_assign(EVP_PKEY_PTR pkey, int typ, void *key); +[[mkcgo::error_only]] int EVP_PKEY_get_raw_private_key(const EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len); +[[mkcgo::error_only]] int EVP_PKEY_get_raw_public_key(const EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len); +[[mkcgo::error_only]] int EVP_PKEY_set1_encoded_public_key(EVP_PKEY_PTR pkey, const unsigned char *pub, size_t publen); +[[mkcgo::error_only]] int EVP_PKEY_set1_EC_KEY(EVP_PKEY_PTR pkey, EC_KEY_PTR key); +[[mkcgo::error_only]] int EVP_PKEY_get_bn_param(const EVP_PKEY_PTR pkey, const char *key_name, BIGNUM_PTR *bn); + +const EVP_MD_PTR EVP_md5_sha1(void); +const EVP_MD_PTR EVP_md4(void); +const EVP_MD_PTR EVP_md5(void); +const EVP_MD_PTR EVP_sha1(void); +const EVP_MD_PTR EVP_sha224(void); +const EVP_MD_PTR EVP_sha256(void); +const EVP_MD_PTR EVP_sha384(void); +const EVP_MD_PTR EVP_sha512(void); +const EVP_MD_PTR EVP_sha3_224(void); +const EVP_MD_PTR EVP_sha3_256(void); +const EVP_MD_PTR EVP_sha3_384(void); +const EVP_MD_PTR EVP_sha3_512(void); + +void EC_KEY_free(EC_KEY_PTR arg0); +[[mkcgo::error]] const EC_GROUP_PTR EC_KEY_get0_group(const EC_KEY_PTR arg0); +[[mkcgo::error]] const BIGNUM_PTR EC_KEY_get0_private_key(const EC_KEY_PTR arg0); +[[mkcgo::error]] const EC_POINT_PTR EC_KEY_get0_public_key(const EC_KEY_PTR arg0); +[[mkcgo::error]] EC_KEY_PTR EC_KEY_new_by_curve_name(int arg0); +[[mkcgo::error_only]] int EC_KEY_set_public_key_affine_coordinates(EC_KEY_PTR key, BIGNUM_PTR x, BIGNUM_PTR y); +[[mkcgo::error_only]] int EC_KEY_set_public_key(EC_KEY_PTR key, const EC_POINT_PTR pub); +[[mkcgo::error_only]] int EC_KEY_set_private_key(EC_KEY_PTR arg0, const BIGNUM_PTR arg1); + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX_PTR arg0); +[[mkcgo::error]] EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new(EVP_PKEY_PTR arg0, ENGINE_PTR arg1); +[[mkcgo::error]] EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_id(int id, ENGINE_PTR e); +[[mkcgo::error]] EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX_PTR libctx, EVP_PKEY_PTR pkey, const char *propquery); +[[mkcgo::error_only]] int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2); +[[mkcgo::error_only]] int EVP_PKEY_decrypt(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); +[[mkcgo::error_only]] int EVP_PKEY_encrypt(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); +[[mkcgo::error_only]] int EVP_PKEY_decrypt_init(EVP_PKEY_CTX_PTR arg0); +[[mkcgo::error_only]] int EVP_PKEY_encrypt_init(EVP_PKEY_CTX_PTR arg0); +[[mkcgo::error_only]] int EVP_PKEY_sign_init(EVP_PKEY_CTX_PTR arg0); +[[mkcgo::error_only]] int EVP_PKEY_verify_init(EVP_PKEY_CTX_PTR arg0); +[[mkcgo::error_only]] int EVP_PKEY_verify(EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); +[[mkcgo::error_only]] int EVP_PKEY_sign(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); +[[mkcgo::error_only]] int EVP_PKEY_derive_init(EVP_PKEY_CTX_PTR ctx); +[[mkcgo::error_only]] int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR peer); +[[mkcgo::error_only]] int EVP_PKEY_derive(EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t *keylen); +[[mkcgo::error_only]] int EVP_PKEY_fromdata_init(EVP_PKEY_CTX_PTR ctx); +[[mkcgo::error_only]] int EVP_PKEY_fromdata(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *pkey, int selection, OSSL_PARAM_PTR params); +[[mkcgo::error_only]] int EVP_PKEY_paramgen_init(EVP_PKEY_CTX_PTR ctx); +[[mkcgo::error_only]] int EVP_PKEY_paramgen(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *ppkey); +[[mkcgo::error_only]] int EVP_PKEY_keygen_init(EVP_PKEY_CTX_PTR ctx); +[[mkcgo::error_only]] int EVP_PKEY_keygen(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *ppkey); +[[mkcgo::error_only]] int EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX_PTR arg0, int arg1); +[[mkcgo::error_only]] int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX_PTR arg0, const EVP_MD_PTR arg1); +[[mkcgo::error_only]] int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); +[[mkcgo::error_only]] int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); +[[mkcgo::error_only]] int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); +[[mkcgo::error_only]] int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX_PTR ctx, void *label, int len); +[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]] EVP_PKEY_PTR EVP_PKEY_Q_keygen_ED25519(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ); +[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]] EVP_PKEY_PTR EVP_PKEY_Q_keygen_RSA(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ, size_t arg1); +[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]] EVP_PKEY_PTR EVP_PKEY_Q_keygen_EC(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ, const char *arg1); + +void RSA_free(RSA_PTR r); +void RSA_get0_crt_params(const RSA_PTR r, const BIGNUM_PTR *dmp1, const BIGNUM_PTR *dmq1, const BIGNUM_PTR *iqmp); +void RSA_get0_factors(const RSA_PTR r, const BIGNUM_PTR *p, const BIGNUM_PTR *q); +void RSA_get0_key(const RSA_PTR r, const BIGNUM_PTR *n, const BIGNUM_PTR *e, const BIGNUM_PTR *d); +[[mkcgo::error]] RSA_PTR RSA_new(void); +[[mkcgo::error_only]] int RSA_set0_key(RSA_PTR r, BIGNUM_PTR n, BIGNUM_PTR e, BIGNUM_PTR d); +[[mkcgo::error_only]] int RSA_set0_factors(RSA_PTR r, BIGNUM_PTR p, BIGNUM_PTR q); +[[mkcgo::error_only]] int RSA_set0_crt_params(RSA_PTR r, BIGNUM_PTR dmp1, BIGNUM_PTR dmq1, BIGNUM_PTR iqmp); + +void DSA_free(DSA_PTR r); +void DSA_get0_pqg(const DSA_PTR d, const BIGNUM_PTR *p, const BIGNUM_PTR *q, const BIGNUM_PTR *g); +void DSA_get0_key(const DSA_PTR d, const BIGNUM_PTR *pub_key, const BIGNUM_PTR *priv_key); +[[mkcgo::error]] DSA_PTR DSA_new(void); +[[mkcgo::error_only]] int DSA_generate_key(DSA_PTR a); +[[mkcgo::error_only]] int DSA_set0_pqg(DSA_PTR d, BIGNUM_PTR p, BIGNUM_PTR q, BIGNUM_PTR g); +[[mkcgo::error_only]] int DSA_set0_key(DSA_PTR d, BIGNUM_PTR pub_key, BIGNUM_PTR priv_key); + +void HMAC_CTX_free(HMAC_CTX_PTR arg0); +void HMAC_CTX_init(HMAC_CTX_PTR arg0); +void HMAC_CTX_cleanup(HMAC_CTX_PTR arg0); +[[mkcgo::error]] HMAC_CTX_PTR HMAC_CTX_new(void); +[[mkcgo::error_only]] int HMAC_CTX_copy(HMAC_CTX_PTR dest, HMAC_CTX_PTR src); +[[mkcgo::error_only]] int HMAC_Init_ex(HMAC_CTX_PTR arg0, const void *arg1, int arg2, const EVP_MD_PTR arg3, ENGINE_PTR arg4); +[[mkcgo::error_only]] int HMAC_Update(HMAC_CTX_PTR arg0, const unsigned char *arg1, size_t arg2); +[[mkcgo::error_only]] int HMAC_Final(HMAC_CTX_PTR arg0, unsigned char *arg1, unsigned int *arg2); + +int OSSL_PROVIDER_available(OSSL_LIB_CTX_PTR libctx, const char *name); +[[mkcgo::error]] OSSL_PROVIDER_PTR OSSL_PROVIDER_try_load(OSSL_LIB_CTX_PTR libctx, const char *name, int retain_fallbacks); +const char *OSSL_PROVIDER_get0_name(const OSSL_PROVIDER_PTR prov); + +void EVP_MD_free(EVP_MD_PTR md); +const char *EVP_MD_get0_name(const EVP_MD_PTR md); +[[mkcgo::name("_EVP_MD_size")]] int EVP_MD_size(const EVP_MD_PTR md); +[[mkcgo::name("_EVP_MD_get_size")]] int EVP_MD_get_size(const EVP_MD_PTR md); +[[mkcgo::name("_EVP_MD_block_size")]] int EVP_MD_block_size(const EVP_MD_PTR md); +[[mkcgo::name("_EVP_MD_get_block_size")]] int EVP_MD_get_block_size(const EVP_MD_PTR md); +[[mkcgo::name("_EVP_MD_CTX_destroy")]] void EVP_MD_CTX_destroy(EVP_MD_CTX_PTR ctx); +[[mkcgo::name("_EVP_MD_CTX_free")]] void EVP_MD_CTX_free(EVP_MD_CTX_PTR ctx); +[[mkcgo::error]] [[mkcgo::name("_EVP_MD_CTX_create")]] EVP_MD_CTX_PTR EVP_MD_CTX_create(void); +[[mkcgo::error]] [[mkcgo::name("_EVP_MD_CTX_new")]] EVP_MD_CTX_PTR EVP_MD_CTX_new(void); +[[mkcgo::error]] const OSSL_PROVIDER_PTR EVP_MD_get0_provider(const EVP_MD_PTR md); +[[mkcgo::error]] EVP_MD_PTR EVP_MD_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +[[mkcgo::error_only]] int EVP_MD_CTX_copy(EVP_MD_CTX_PTR out, const EVP_MD_CTX_PTR in); +[[mkcgo::error_only]] int EVP_MD_CTX_copy_ex(EVP_MD_CTX_PTR out, const EVP_MD_CTX_PTR in); +[[mkcgo::error_only]] int EVP_Digest(const void *data, size_t count, unsigned char *md, unsigned int *size, const EVP_MD_PTR typ, ENGINE_PTR impl); +[[mkcgo::error_only]] int EVP_DigestInit_ex(EVP_MD_CTX_PTR ctx, const EVP_MD_PTR typ, ENGINE_PTR impl); +[[mkcgo::error_only]] int EVP_DigestInit(EVP_MD_CTX_PTR ctx, const EVP_MD_PTR typ); +[[mkcgo::error_only]] int EVP_DigestUpdate(EVP_MD_CTX_PTR ctx, const void *d, size_t cnt); +[[mkcgo::error_only]] int EVP_DigestFinal(EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s); +[[mkcgo::error_only]] int EVP_DigestSign(EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen); +[[mkcgo::error_only]] int EVP_DigestSignInit(EVP_MD_CTX_PTR ctx, EVP_PKEY_CTX_PTR *pctx, const EVP_MD_PTR typ, ENGINE_PTR e, EVP_PKEY_PTR pkey); +[[mkcgo::error_only]] int EVP_DigestSignFinal(EVP_MD_CTX_PTR ctx, unsigned char *sig, size_t *siglen); +[[mkcgo::error_only]] int EVP_DigestVerifyInit(EVP_MD_CTX_PTR ctx, EVP_PKEY_CTX_PTR *pctx, const EVP_MD_PTR typ, ENGINE_PTR e, EVP_PKEY_PTR pkey); +[[mkcgo::error_only]] int EVP_DigestVerifyFinal(EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen); +[[mkcgo::error_only]] int EVP_DigestVerify(EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen); +[[mkcgo::error_only]] int MD5_Init(MD5_CTX_PTR c); +[[mkcgo::error_only]] int MD5_Update(MD5_CTX_PTR c, const void *data, size_t len); +[[mkcgo::error_only]] int MD5_Final(unsigned char *md, MD5_CTX_PTR c); +[[mkcgo::error_only]] int SHA1_Init(SHA_CTX_PTR c); +[[mkcgo::error_only]] int SHA1_Update(SHA_CTX_PTR c, const void *data, size_t len); +[[mkcgo::error_only]] int SHA1_Final(unsigned char *md, SHA_CTX_PTR c); + +void BN_free(BIGNUM_PTR arg0); +void BN_clear(BIGNUM_PTR arg0); +void BN_clear_free(BIGNUM_PTR arg0); +int BN_num_bits(const BIGNUM_PTR arg0); +int BN_bn2bin(const BIGNUM_PTR a, unsigned char *to); +[[mkcgo::error]] BIGNUM_PTR BN_new(void); +[[mkcgo::error]] BIGNUM_PTR BN_bin2bn(const unsigned char *arg0, int arg1, BIGNUM_PTR arg2); +[[mkcgo::error]] [[mkcgo::name("BN_expand2")]] BIGNUM_PTR bn_expand2(BIGNUM_PTR a, int n); +[[mkcgo::error]] BIGNUM_PTR BN_lebin2bn(const unsigned char *s, int len, BIGNUM_PTR ret); +[[mkcgo::error("retval == -1")]] int BN_bn2lebinpad(const BIGNUM_PTR a, unsigned char *to, int tolen); +[[mkcgo::error("retval == -1")]] int BN_bn2binpad(const BIGNUM_PTR a, unsigned char *to, int tolen); + + +void EC_POINT_free(EC_POINT_PTR arg0); +[[mkcgo::error]] EC_POINT_PTR EC_POINT_new(const EC_GROUP_PTR arg0); +[[mkcgo::error("retval == 0")]] size_t EC_POINT_point2oct(const EC_GROUP_PTR group, const EC_POINT_PTR p, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX_PTR ctx); +[[mkcgo::error_only]] int EC_POINT_mul(const EC_GROUP_PTR group, EC_POINT_PTR r, const BIGNUM_PTR n, const EC_POINT_PTR q, const BIGNUM_PTR m, BN_CTX_PTR ctx); +[[mkcgo::error_only]] int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP_PTR arg0, const EC_POINT_PTR arg1, BIGNUM_PTR arg2, BIGNUM_PTR arg3, BN_CTX_PTR arg4); +[[mkcgo::error_only]] int EC_POINT_set_affine_coordinates(const EC_GROUP_PTR arg0, EC_POINT_PTR arg1, const BIGNUM_PTR arg2, const BIGNUM_PTR arg3, BN_CTX_PTR arg4); +[[mkcgo::error_only]] int EC_POINT_oct2point(const EC_GROUP_PTR group, EC_POINT_PTR p, const unsigned char *buf, size_t len, BN_CTX_PTR ctx); + +const char *OBJ_nid2sn(int n); + +[[mkcgo::error]] EC_GROUP_PTR EC_GROUP_new_by_curve_name(int nid); +void EC_GROUP_free(EC_GROUP_PTR group); + +void EVP_MAC_CTX_free(EVP_MAC_CTX_PTR arg0); +[[mkcgo::error]] EVP_MAC_PTR EVP_MAC_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +[[mkcgo::error]] EVP_MAC_CTX_PTR EVP_MAC_CTX_new(EVP_MAC_PTR arg0); +[[mkcgo::error]] EVP_MAC_CTX_PTR EVP_MAC_CTX_dup(const EVP_MAC_CTX_PTR arg0); +[[mkcgo::error_only]] int EVP_MAC_CTX_set_params(EVP_MAC_CTX_PTR ctx, const OSSL_PARAM_PTR params); +[[mkcgo::error_only]] int EVP_MAC_init(EVP_MAC_CTX_PTR ctx, const unsigned char *key, size_t keylen, const OSSL_PARAM_PTR params); +[[mkcgo::error_only]] int EVP_MAC_update(EVP_MAC_CTX_PTR ctx, const unsigned char *data, size_t datalen); +[[mkcgo::error_only]] int EVP_MAC_final(EVP_MAC_CTX_PTR ctx, unsigned char *out, size_t *outl, size_t outsize); + +void OSSL_PARAM_free(OSSL_PARAM_PTR p); + +void OSSL_PARAM_BLD_free(OSSL_PARAM_BLD_PTR bld); +[[mkcgo::error]] OSSL_PARAM_BLD_PTR OSSL_PARAM_BLD_new(void); +[[mkcgo::error]] OSSL_PARAM_PTR OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD_PTR bld); +[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD_PTR bld, const char *key, const char *buf, size_t bsize); +[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD_PTR bld, const char *key, const void *buf, size_t bsize); +[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD_PTR bld, const char *key, const BIGNUM_PTR bn); +[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD_PTR bld, const char *key, int32_t num); + +[[mkcgo::error_only]] int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD_PTR digest, int keylen, unsigned char *out); + +void EVP_SIGNATURE_free(EVP_SIGNATURE_PTR signature); +[[mkcgo::error]] EVP_SIGNATURE_PTR EVP_SIGNATURE_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); + +void EVP_KDF_free(EVP_KDF_PTR kdf); +[[mkcgo::error]] EVP_KDF_CTX_PTR EVP_KDF_CTX_new(EVP_KDF_PTR kdf); +[[mkcgo::error]] EVP_KDF_PTR EVP_KDF_fetch(OSSL_LIB_CTX_PTR libctx, const char *algorithm, const char *properties); + +void EVP_KDF_CTX_free(EVP_KDF_CTX_PTR ctx); +[[mkcgo::error("retval == 0")]] size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX_PTR ctx); +[[mkcgo::error_only]] int EVP_KDF_CTX_set_params(EVP_KDF_CTX_PTR ctx, const OSSL_PARAM_PTR params); +[[mkcgo::error_only]] int EVP_KDF_derive(EVP_KDF_CTX_PTR ctx, unsigned char *key, size_t keylen, const OSSL_PARAM_PTR params); + diff --git a/internal/ossl/const.go b/internal/ossl/const.go new file mode 100644 index 00000000..acd1cace --- /dev/null +++ b/internal/ossl/const.go @@ -0,0 +1,127 @@ +package ossl + +const ( + KeyTypeRSA = "RSA\x00" + KeyTypeEC = "EC\x00" + KeyTypeED25519 = "ED25519\x00" +) + +const ( + OSSL_KDF_NAME_HKDF = "HKDF\x00" + OSSL_KDF_NAME_PBKDF2 = "PBKDF2\x00" + OSSL_KDF_NAME_TLS1_PRF = "TLS1-PRF\x00" + OSSL_MAC_NAME_HMAC = "HMAC\x00" +) + +const POINT_CONVERSION_UNCOMPRESSED = 4 + +// #include +const ( + OPENSSL_INIT_LOAD_CRYPTO_STRINGS = 0x00000002 + OPENSSL_INIT_ADD_ALL_CIPHERS = 0x00000004 + OPENSSL_INIT_ADD_ALL_DIGESTS = 0x00000008 + OPENSSL_INIT_LOAD_CONFIG = 0x00000040 +) + +// #include +const ( + 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. + */ + GO1_EVP_PKEY_OP_DERIVE = (1 << 10) + EVP_MAX_MD_SIZE = 64 + + EVP_PKEY_PUBLIC_KEY = 0x86 + EVP_PKEY_KEYPAIR = 0x87 +) + +// #include +const ( + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = 0x1001 +) + +// #include +const ( + 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 +) + +// #include +const ( + NID_X9_62_prime256v1 = 415 + NID_secp224r1 = 713 + NID_secp384r1 = 715 + NID_secp521r1 = 716 +) + +// #include +const ( + 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 +) + +const ( + // KDF parameters + OSSL_KDF_PARAM_DIGEST = "digest\x00" + OSSL_KDF_PARAM_SECRET = "secret\x00" + OSSL_KDF_PARAM_SEED = "seed\x00" + OSSL_KDF_PARAM_KEY = "key\x00" + OSSL_KDF_PARAM_INFO = "info\x00" + OSSL_KDF_PARAM_SALT = "salt\x00" + OSSL_KDF_PARAM_MODE = "mode\x00" + + // PKEY parameters + OSSL_PKEY_PARAM_PUB_KEY = "pub\x00" + OSSL_PKEY_PARAM_PRIV_KEY = "priv\x00" + OSSL_PKEY_PARAM_GROUP_NAME = "group\x00" + OSSL_PKEY_PARAM_EC_PUB_X = "qx\x00" + OSSL_PKEY_PARAM_EC_PUB_Y = "qy\x00" + OSSL_PKEY_PARAM_FFC_PBITS = "pbits\x00" + OSSL_PKEY_PARAM_FFC_QBITS = "qbits\x00" + OSSL_PKEY_PARAM_RSA_N = "n\x00" + OSSL_PKEY_PARAM_RSA_E = "e\x00" + OSSL_PKEY_PARAM_RSA_D = "d\x00" + OSSL_PKEY_PARAM_FFC_P = "p\x00" + OSSL_PKEY_PARAM_FFC_Q = "q\x00" + OSSL_PKEY_PARAM_FFC_G = "g\x00" + OSSL_PKEY_PARAM_RSA_FACTOR1 = "rsa-factor1\x00" + OSSL_PKEY_PARAM_RSA_FACTOR2 = "rsa-factor2\x00" + OSSL_PKEY_PARAM_RSA_EXPONENT1 = "rsa-exponent1\x00" + OSSL_PKEY_PARAM_RSA_EXPONENT2 = "rsa-exponent2\x00" + OSSL_PKEY_PARAM_RSA_COEFFICIENT1 = "rsa-coefficient1\x00" + + // MAC parameters + OSSL_MAC_PARAM_DIGEST = "digest\x00" +) diff --git a/internal/ossl/ossl.go b/internal/ossl/ossl.go new file mode 100644 index 00000000..2d163d1a --- /dev/null +++ b/internal/ossl/ossl.go @@ -0,0 +1,5 @@ +//go:build cgo + +package ossl + +//go:generate go run github.com/golang-fips/openssl/v2/internal/mkcgo -out zossl.go --package ossl --lib crypto --include ossl.h api.h diff --git a/internal/ossl/ossl.h b/internal/ossl/ossl.h new file mode 100644 index 00000000..90c64023 --- /dev/null +++ b/internal/ossl/ossl.h @@ -0,0 +1,50 @@ + +#pragma GCC diagnostic ignored "-Wattributes" + +#ifndef OSSL_H +#define OSSL_H + +// Suppress warnings about unused parameters. +#define UNUSED(x) (void)(x) + +// #include +enum { + EVP_CTRL_GCM_GET_TAG = 0x10, + EVP_CTRL_GCM_SET_TAG = 0x11, +}; + +typedef int point_conversion_form_t; + +typedef void* OPENSSL_INIT_SETTINGS_PTR; +typedef void* OSSL_LIB_CTX_PTR; +typedef void* OSSL_PROVIDER_PTR; +typedef void* ENGINE_PTR; +typedef void* EVP_PKEY_PTR; +typedef void* EVP_PKEY_CTX_PTR; +typedef void* EVP_MD_PTR; +typedef void* EVP_MD_CTX_PTR; +typedef void* HMAC_CTX_PTR; +typedef void* EVP_CIPHER_PTR; +typedef void* EVP_CIPHER_CTX_PTR; +typedef void* EC_KEY_PTR; +typedef void* EC_POINT_PTR; +typedef void* EC_GROUP_PTR; +typedef void* RSA_PTR; +typedef void* BIGNUM_PTR; +typedef void* BN_CTX_PTR; +typedef void* EVP_MAC_PTR; +typedef void* EVP_MAC_CTX_PTR; +typedef void* OSSL_PARAM_BLD_PTR; +typedef void* OSSL_PARAM_PTR; +typedef void* CRYPTO_THREADID_PTR; +typedef void* EVP_SIGNATURE_PTR; +typedef void* DSA_PTR; +typedef void* EVP_KDF_PTR; +typedef void* EVP_KDF_CTX_PTR; +typedef void* MD5_CTX_PTR; +typedef void* SHA_CTX_PTR; + +typedef void threadid_func(CRYPTO_THREADID_PTR); +typedef void locking_func(int mode, int n, const char *file, int line); + +#endif // OSSL_H \ No newline at end of file diff --git a/internal/ossl/ossl_cgo.go b/internal/ossl/ossl_cgo.go new file mode 100644 index 00000000..7dd9bedb --- /dev/null +++ b/internal/ossl/ossl_cgo.go @@ -0,0 +1,36 @@ +//go:build cgo + +package ossl + +import "C" + +type Point_conversion_form_t = C.point_conversion_form_t + +type OPENSSL_INIT_SETTINGS_PTR = C.OPENSSL_INIT_SETTINGS_PTR +type OSSL_LIB_CTX_PTR = C.OSSL_LIB_CTX_PTR +type OSSL_PROVIDER_PTR = C.OSSL_PROVIDER_PTR +type ENGINE_PTR = C.ENGINE_PTR +type EVP_PKEY_PTR = C.EVP_PKEY_PTR +type EVP_PKEY_CTX_PTR = C.EVP_PKEY_CTX_PTR +type EVP_MD_PTR = C.EVP_MD_PTR +type EVP_MD_CTX_PTR = C.EVP_MD_CTX_PTR +type HMAC_CTX_PTR = C.HMAC_CTX_PTR +type EVP_CIPHER_PTR = C.EVP_CIPHER_PTR +type EVP_CIPHER_CTX_PTR = C.EVP_CIPHER_CTX_PTR +type EC_KEY_PTR = C.EC_KEY_PTR +type EC_POINT_PTR = C.EC_POINT_PTR +type EC_GROUP_PTR = C.EC_GROUP_PTR +type RSA_PTR = C.RSA_PTR +type BIGNUM_PTR = C.BIGNUM_PTR +type BN_CTX_PTR = C.BN_CTX_PTR +type EVP_MAC_PTR = C.EVP_MAC_PTR +type EVP_MAC_CTX_PTR = C.EVP_MAC_CTX_PTR +type OSSL_PARAM_BLD_PTR = C.OSSL_PARAM_BLD_PTR +type OSSL_PARAM_PTR = C.OSSL_PARAM_PTR +type CRYPTO_THREADID_PTR = C.CRYPTO_THREADID_PTR +type EVP_SIGNATURE_PTR = C.EVP_SIGNATURE_PTR +type DSA_PTR = C.DSA_PTR +type EVP_KDF_PTR = C.EVP_KDF_PTR +type EVP_KDF_CTX_PTR = C.EVP_KDF_CTX_PTR +type MD5_CTX_PTR = C.MD5_CTX_PTR +type SHA_CTX_PTR = C.SHA_CTX_PTR diff --git a/internal/ossl/zossl.c b/internal/ossl/zossl.c new file mode 100644 index 00000000..67540d1c --- /dev/null +++ b/internal/ossl/zossl.c @@ -0,0 +1,1404 @@ +// Code generated by mkcgo. DO NOT EDIT. + +#include "ossl.h" +#include +#include +#include + +#ifdef _WIN32 +#include +#define dlsym GetProcAddress +#else +#include +#endif + +BIGNUM_PTR (*_g_BN_bin2bn)(const unsigned char*, int, BIGNUM_PTR); +int (*_g_BN_bn2bin)(const BIGNUM_PTR, unsigned char*); +int (*_g_BN_bn2binpad)(const BIGNUM_PTR, unsigned char*, int); +int (*_g_BN_bn2lebinpad)(const BIGNUM_PTR, unsigned char*, int); +void (*_g_BN_clear)(BIGNUM_PTR); +void (*_g_BN_clear_free)(BIGNUM_PTR); +void (*_g_BN_free)(BIGNUM_PTR); +BIGNUM_PTR (*_g_BN_lebin2bn)(const unsigned char*, int, BIGNUM_PTR); +BIGNUM_PTR (*_g_BN_new)(void); +int (*_g_BN_num_bits)(const BIGNUM_PTR); +int (*_g_CRYPTO_THREADID_set_callback)(threadid_func); +void (*_g_CRYPTO_THREADID_set_numeric)(CRYPTO_THREADID_PTR, unsigned long); +void (*_g_CRYPTO_free)(void*, const char*, int); +void* (*_g_CRYPTO_malloc)(size_t, const char*, int); +int (*_g_CRYPTO_num_locks)(void); +void (*_g_CRYPTO_set_locking_callback)(locking_func); +void (*_g_DSA_free)(DSA_PTR); +int (*_g_DSA_generate_key)(DSA_PTR); +void (*_g_DSA_get0_key)(const DSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*); +void (*_g_DSA_get0_pqg)(const DSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*, const BIGNUM_PTR*); +DSA_PTR (*_g_DSA_new)(void); +int (*_g_DSA_set0_key)(DSA_PTR, BIGNUM_PTR, BIGNUM_PTR); +int (*_g_DSA_set0_pqg)(DSA_PTR, BIGNUM_PTR, BIGNUM_PTR, BIGNUM_PTR); +void (*_g_EC_GROUP_free)(EC_GROUP_PTR); +EC_GROUP_PTR (*_g_EC_GROUP_new_by_curve_name)(int); +void (*_g_EC_KEY_free)(EC_KEY_PTR); +const EC_GROUP_PTR (*_g_EC_KEY_get0_group)(const EC_KEY_PTR); +const BIGNUM_PTR (*_g_EC_KEY_get0_private_key)(const EC_KEY_PTR); +const EC_POINT_PTR (*_g_EC_KEY_get0_public_key)(const EC_KEY_PTR); +EC_KEY_PTR (*_g_EC_KEY_new_by_curve_name)(int); +int (*_g_EC_KEY_set_private_key)(EC_KEY_PTR, const BIGNUM_PTR); +int (*_g_EC_KEY_set_public_key)(EC_KEY_PTR, const EC_POINT_PTR); +int (*_g_EC_KEY_set_public_key_affine_coordinates)(EC_KEY_PTR, BIGNUM_PTR, BIGNUM_PTR); +void (*_g_EC_POINT_free)(EC_POINT_PTR); +int (*_g_EC_POINT_get_affine_coordinates_GFp)(const EC_GROUP_PTR, const EC_POINT_PTR, BIGNUM_PTR, BIGNUM_PTR, BN_CTX_PTR); +int (*_g_EC_POINT_mul)(const EC_GROUP_PTR, EC_POINT_PTR, const BIGNUM_PTR, const EC_POINT_PTR, const BIGNUM_PTR, BN_CTX_PTR); +EC_POINT_PTR (*_g_EC_POINT_new)(const EC_GROUP_PTR); +int (*_g_EC_POINT_oct2point)(const EC_GROUP_PTR, EC_POINT_PTR, const unsigned char*, size_t, BN_CTX_PTR); +size_t (*_g_EC_POINT_point2oct)(const EC_GROUP_PTR, const EC_POINT_PTR, point_conversion_form_t, unsigned char*, size_t, BN_CTX_PTR); +int (*_g_EC_POINT_set_affine_coordinates)(const EC_GROUP_PTR, EC_POINT_PTR, const BIGNUM_PTR, const BIGNUM_PTR, BN_CTX_PTR); +void (*_g_ERR_clear_error)(void); +void (*_g_ERR_error_string_n)(unsigned long, char*, size_t); +unsigned long (*_g_ERR_get_error_all)(const char**, int*, const char**, const char**, int*); +unsigned long (*_g_ERR_get_error_line)(const char**, int*); +void (*_g_ERR_load_crypto_strings)(void); +void (*_g_ERR_remove_thread_state)(const CRYPTO_THREADID_PTR); +int (*_g_EVP_CIPHER_CTX_ctrl)(EVP_CIPHER_CTX_PTR, int, int, void*); +void (*_g_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX_PTR); +EVP_CIPHER_CTX_PTR (*_g_EVP_CIPHER_CTX_new)(void); +int (*_g_EVP_CIPHER_CTX_set_key_length)(EVP_CIPHER_CTX_PTR, int); +int (*_g_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX_PTR, int); +int (*_g_EVP_CIPHER_block_size)(const EVP_CIPHER_PTR); +EVP_CIPHER_PTR (*_g_EVP_CIPHER_fetch)(OSSL_LIB_CTX_PTR, const char*, const char*); +const char* (*_g_EVP_CIPHER_get0_name)(const EVP_CIPHER_PTR); +int (*_g_EVP_CIPHER_get_block_size)(const EVP_CIPHER_PTR); +int (*_g_EVP_CipherInit_ex)(EVP_CIPHER_CTX_PTR, const EVP_CIPHER_PTR, ENGINE_PTR, const unsigned char*, const unsigned char*, int); +int (*_g_EVP_CipherUpdate)(EVP_CIPHER_CTX_PTR, unsigned char*, int*, const unsigned char*, int); +int (*_g_EVP_DecryptFinal_ex)(EVP_CIPHER_CTX_PTR, unsigned char*, int*); +int (*_g_EVP_DecryptInit_ex)(EVP_CIPHER_CTX_PTR, const EVP_CIPHER_PTR, ENGINE_PTR, const unsigned char*, const unsigned char*); +int (*_g_EVP_DecryptUpdate)(EVP_CIPHER_CTX_PTR, unsigned char*, int*, const unsigned char*, int); +int (*_g_EVP_Digest)(const void*, size_t, unsigned char*, unsigned int*, const EVP_MD_PTR, ENGINE_PTR); +int (*_g_EVP_DigestFinal)(EVP_MD_CTX_PTR, unsigned char*, unsigned int*); +int (*_g_EVP_DigestInit)(EVP_MD_CTX_PTR, const EVP_MD_PTR); +int (*_g_EVP_DigestInit_ex)(EVP_MD_CTX_PTR, const EVP_MD_PTR, ENGINE_PTR); +int (*_g_EVP_DigestSign)(EVP_MD_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t); +int (*_g_EVP_DigestSignFinal)(EVP_MD_CTX_PTR, unsigned char*, size_t*); +int (*_g_EVP_DigestSignInit)(EVP_MD_CTX_PTR, EVP_PKEY_CTX_PTR*, const EVP_MD_PTR, ENGINE_PTR, EVP_PKEY_PTR); +int (*_g_EVP_DigestUpdate)(EVP_MD_CTX_PTR, const void*, size_t); +int (*_g_EVP_DigestVerify)(EVP_MD_CTX_PTR, const unsigned char*, size_t, const unsigned char*, size_t); +int (*_g_EVP_DigestVerifyFinal)(EVP_MD_CTX_PTR, const unsigned char*, size_t); +int (*_g_EVP_DigestVerifyInit)(EVP_MD_CTX_PTR, EVP_PKEY_CTX_PTR*, const EVP_MD_PTR, ENGINE_PTR, EVP_PKEY_PTR); +int (*_g_EVP_EncryptFinal_ex)(EVP_CIPHER_CTX_PTR, unsigned char*, int*); +int (*_g_EVP_EncryptInit_ex)(EVP_CIPHER_CTX_PTR, const EVP_CIPHER_PTR, ENGINE_PTR, const unsigned char*, const unsigned char*); +int (*_g_EVP_EncryptUpdate)(EVP_CIPHER_CTX_PTR, unsigned char*, int*, const unsigned char*, int); +void (*_g_EVP_KDF_CTX_free)(EVP_KDF_CTX_PTR); +size_t (*_g_EVP_KDF_CTX_get_kdf_size)(EVP_KDF_CTX_PTR); +EVP_KDF_CTX_PTR (*_g_EVP_KDF_CTX_new)(EVP_KDF_PTR); +int (*_g_EVP_KDF_CTX_set_params)(EVP_KDF_CTX_PTR, const OSSL_PARAM_PTR); +int (*_g_EVP_KDF_derive)(EVP_KDF_CTX_PTR, unsigned char*, size_t, const OSSL_PARAM_PTR); +EVP_KDF_PTR (*_g_EVP_KDF_fetch)(OSSL_LIB_CTX_PTR, const char*, const char*); +void (*_g_EVP_KDF_free)(EVP_KDF_PTR); +EVP_MAC_CTX_PTR (*_g_EVP_MAC_CTX_dup)(const EVP_MAC_CTX_PTR); +void (*_g_EVP_MAC_CTX_free)(EVP_MAC_CTX_PTR); +EVP_MAC_CTX_PTR (*_g_EVP_MAC_CTX_new)(EVP_MAC_PTR); +int (*_g_EVP_MAC_CTX_set_params)(EVP_MAC_CTX_PTR, const OSSL_PARAM_PTR); +EVP_MAC_PTR (*_g_EVP_MAC_fetch)(OSSL_LIB_CTX_PTR, const char*, const char*); +int (*_g_EVP_MAC_final)(EVP_MAC_CTX_PTR, unsigned char*, size_t*, size_t); +int (*_g_EVP_MAC_init)(EVP_MAC_CTX_PTR, const unsigned char*, size_t, const OSSL_PARAM_PTR); +int (*_g_EVP_MAC_update)(EVP_MAC_CTX_PTR, const unsigned char*, size_t); +int (*_g_EVP_MD_CTX_copy)(EVP_MD_CTX_PTR, const EVP_MD_CTX_PTR); +int (*_g_EVP_MD_CTX_copy_ex)(EVP_MD_CTX_PTR, const EVP_MD_CTX_PTR); +EVP_MD_CTX_PTR (*_g_EVP_MD_CTX_create)(void); +void (*_g_EVP_MD_CTX_destroy)(EVP_MD_CTX_PTR); +void (*_g_EVP_MD_CTX_free)(EVP_MD_CTX_PTR); +EVP_MD_CTX_PTR (*_g_EVP_MD_CTX_new)(void); +int (*_g_EVP_MD_block_size)(const EVP_MD_PTR); +EVP_MD_PTR (*_g_EVP_MD_fetch)(OSSL_LIB_CTX_PTR, const char*, const char*); +void (*_g_EVP_MD_free)(EVP_MD_PTR); +const char* (*_g_EVP_MD_get0_name)(const EVP_MD_PTR); +const OSSL_PROVIDER_PTR (*_g_EVP_MD_get0_provider)(const EVP_MD_PTR); +int (*_g_EVP_MD_get_block_size)(const EVP_MD_PTR); +int (*_g_EVP_MD_get_size)(const EVP_MD_PTR); +int (*_g_EVP_MD_size)(const EVP_MD_PTR); +int (*_g_EVP_PKEY_CTX_add1_hkdf_info)(EVP_PKEY_CTX_PTR, const unsigned char*, int); +int (*_g_EVP_PKEY_CTX_ctrl)(EVP_PKEY_CTX_PTR, int, int, int, int, void*); +void (*_g_EVP_PKEY_CTX_free)(EVP_PKEY_CTX_PTR); +EVP_PKEY_CTX_PTR (*_g_EVP_PKEY_CTX_new)(EVP_PKEY_PTR, ENGINE_PTR); +EVP_PKEY_CTX_PTR (*_g_EVP_PKEY_CTX_new_from_pkey)(OSSL_LIB_CTX_PTR, EVP_PKEY_PTR, const char*); +EVP_PKEY_CTX_PTR (*_g_EVP_PKEY_CTX_new_id)(int, ENGINE_PTR); +int (*_g_EVP_PKEY_CTX_set0_rsa_oaep_label)(EVP_PKEY_CTX_PTR, void*, int); +int (*_g_EVP_PKEY_CTX_set1_hkdf_key)(EVP_PKEY_CTX_PTR, const unsigned char*, int); +int (*_g_EVP_PKEY_CTX_set1_hkdf_salt)(EVP_PKEY_CTX_PTR, const unsigned char*, int); +int (*_g_EVP_PKEY_CTX_set_hkdf_md)(EVP_PKEY_CTX_PTR, const EVP_MD_PTR); +int (*_g_EVP_PKEY_CTX_set_hkdf_mode)(EVP_PKEY_CTX_PTR, int); +EVP_PKEY_PTR (*_g_EVP_PKEY_Q_keygen_EC)(OSSL_LIB_CTX_PTR, const char*, const char*, const char*); +EVP_PKEY_PTR (*_g_EVP_PKEY_Q_keygen_ED25519)(OSSL_LIB_CTX_PTR, const char*, const char*); +EVP_PKEY_PTR (*_g_EVP_PKEY_Q_keygen_RSA)(OSSL_LIB_CTX_PTR, const char*, const char*, size_t); +int (*_g_EVP_PKEY_assign)(EVP_PKEY_PTR, int, void*); +int (*_g_EVP_PKEY_bits)(const EVP_PKEY_PTR); +int (*_g_EVP_PKEY_decrypt)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t); +int (*_g_EVP_PKEY_decrypt_init)(EVP_PKEY_CTX_PTR); +int (*_g_EVP_PKEY_derive)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*); +int (*_g_EVP_PKEY_derive_init)(EVP_PKEY_CTX_PTR); +int (*_g_EVP_PKEY_derive_set_peer)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR); +int (*_g_EVP_PKEY_encrypt)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t); +int (*_g_EVP_PKEY_encrypt_init)(EVP_PKEY_CTX_PTR); +void (*_g_EVP_PKEY_free)(EVP_PKEY_PTR); +int (*_g_EVP_PKEY_fromdata)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR*, int, OSSL_PARAM_PTR); +int (*_g_EVP_PKEY_fromdata_init)(EVP_PKEY_CTX_PTR); +void* (*_g_EVP_PKEY_get0)(const EVP_PKEY_PTR); +const DSA_PTR (*_g_EVP_PKEY_get0_DSA)(const EVP_PKEY_PTR); +const EC_KEY_PTR (*_g_EVP_PKEY_get0_EC_KEY)(const EVP_PKEY_PTR); +RSA_PTR (*_g_EVP_PKEY_get1_RSA)(EVP_PKEY_PTR); +size_t (*_g_EVP_PKEY_get1_encoded_public_key)(EVP_PKEY_PTR, unsigned char**); +int (*_g_EVP_PKEY_get_bits)(const EVP_PKEY_PTR); +int (*_g_EVP_PKEY_get_bn_param)(const EVP_PKEY_PTR, const char*, BIGNUM_PTR*); +int (*_g_EVP_PKEY_get_raw_private_key)(const EVP_PKEY_PTR, unsigned char*, size_t*); +int (*_g_EVP_PKEY_get_raw_public_key)(const EVP_PKEY_PTR, unsigned char*, size_t*); +int (*_g_EVP_PKEY_get_size)(const EVP_PKEY_PTR); +int (*_g_EVP_PKEY_keygen)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR*); +int (*_g_EVP_PKEY_keygen_init)(EVP_PKEY_CTX_PTR); +EVP_PKEY_PTR (*_g_EVP_PKEY_new)(void); +EVP_PKEY_PTR (*_g_EVP_PKEY_new_raw_private_key)(int, ENGINE_PTR, const unsigned char*, size_t); +EVP_PKEY_PTR (*_g_EVP_PKEY_new_raw_public_key)(int, ENGINE_PTR, const unsigned char*, size_t); +int (*_g_EVP_PKEY_paramgen)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR*); +int (*_g_EVP_PKEY_paramgen_init)(EVP_PKEY_CTX_PTR); +int (*_g_EVP_PKEY_set1_EC_KEY)(EVP_PKEY_PTR, EC_KEY_PTR); +int (*_g_EVP_PKEY_set1_encoded_public_key)(EVP_PKEY_PTR, const unsigned char*, size_t); +int (*_g_EVP_PKEY_sign)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t); +int (*_g_EVP_PKEY_sign_init)(EVP_PKEY_CTX_PTR); +int (*_g_EVP_PKEY_size)(const EVP_PKEY_PTR); +int (*_g_EVP_PKEY_up_ref)(EVP_PKEY_PTR); +int (*_g_EVP_PKEY_verify)(EVP_PKEY_CTX_PTR, const unsigned char*, size_t, const unsigned char*, size_t); +int (*_g_EVP_PKEY_verify_init)(EVP_PKEY_CTX_PTR); +EVP_SIGNATURE_PTR (*_g_EVP_SIGNATURE_fetch)(OSSL_LIB_CTX_PTR, const char*, const char*); +void (*_g_EVP_SIGNATURE_free)(EVP_SIGNATURE_PTR); +EVP_CIPHER_PTR (*_g_EVP_aes_128_cbc)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_128_ctr)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_128_ecb)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_128_gcm)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_192_cbc)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_192_ctr)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_192_ecb)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_192_gcm)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_256_cbc)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_256_ctr)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_256_ecb)(void); +EVP_CIPHER_PTR (*_g_EVP_aes_256_gcm)(void); +int (*_g_EVP_default_properties_enable_fips)(OSSL_LIB_CTX_PTR, int); +int (*_g_EVP_default_properties_is_fips_enabled)(OSSL_LIB_CTX_PTR); +EVP_CIPHER_PTR (*_g_EVP_des_cbc)(void); +EVP_CIPHER_PTR (*_g_EVP_des_ecb)(void); +EVP_CIPHER_PTR (*_g_EVP_des_ede3_cbc)(void); +EVP_CIPHER_PTR (*_g_EVP_des_ede3_ecb)(void); +const EVP_MD_PTR (*_g_EVP_md4)(void); +const EVP_MD_PTR (*_g_EVP_md5)(void); +const EVP_MD_PTR (*_g_EVP_md5_sha1)(void); +EVP_CIPHER_PTR (*_g_EVP_rc4)(void); +const EVP_MD_PTR (*_g_EVP_sha1)(void); +const EVP_MD_PTR (*_g_EVP_sha224)(void); +const EVP_MD_PTR (*_g_EVP_sha256)(void); +const EVP_MD_PTR (*_g_EVP_sha384)(void); +const EVP_MD_PTR (*_g_EVP_sha3_224)(void); +const EVP_MD_PTR (*_g_EVP_sha3_256)(void); +const EVP_MD_PTR (*_g_EVP_sha3_384)(void); +const EVP_MD_PTR (*_g_EVP_sha3_512)(void); +const EVP_MD_PTR (*_g_EVP_sha512)(void); +int (*_g_FIPS_mode)(void); +int (*_g_FIPS_mode_set)(int); +void (*_g_HMAC_CTX_cleanup)(HMAC_CTX_PTR); +int (*_g_HMAC_CTX_copy)(HMAC_CTX_PTR, HMAC_CTX_PTR); +void (*_g_HMAC_CTX_free)(HMAC_CTX_PTR); +void (*_g_HMAC_CTX_init)(HMAC_CTX_PTR); +HMAC_CTX_PTR (*_g_HMAC_CTX_new)(void); +int (*_g_HMAC_Final)(HMAC_CTX_PTR, unsigned char*, unsigned int*); +int (*_g_HMAC_Init_ex)(HMAC_CTX_PTR, const void*, int, const EVP_MD_PTR, ENGINE_PTR); +int (*_g_HMAC_Update)(HMAC_CTX_PTR, const unsigned char*, size_t); +int (*_g_MD5_Final)(unsigned char*, MD5_CTX_PTR); +int (*_g_MD5_Init)(MD5_CTX_PTR); +int (*_g_MD5_Update)(MD5_CTX_PTR, const void*, size_t); +const char* (*_g_OBJ_nid2sn)(int); +void (*_g_OPENSSL_add_all_algorithms_conf)(void); +void (*_g_OPENSSL_init)(void); +int (*_g_OPENSSL_init_crypto)(uint64_t, const OPENSSL_INIT_SETTINGS_PTR); +void (*_g_OSSL_PARAM_BLD_free)(OSSL_PARAM_BLD_PTR); +OSSL_PARAM_BLD_PTR (*_g_OSSL_PARAM_BLD_new)(void); +int (*_g_OSSL_PARAM_BLD_push_BN)(OSSL_PARAM_BLD_PTR, const char*, const BIGNUM_PTR); +int (*_g_OSSL_PARAM_BLD_push_int32)(OSSL_PARAM_BLD_PTR, const char*, int32_t); +int (*_g_OSSL_PARAM_BLD_push_octet_string)(OSSL_PARAM_BLD_PTR, const char*, const void*, size_t); +int (*_g_OSSL_PARAM_BLD_push_utf8_string)(OSSL_PARAM_BLD_PTR, const char*, const char*, size_t); +OSSL_PARAM_PTR (*_g_OSSL_PARAM_BLD_to_param)(OSSL_PARAM_BLD_PTR); +void (*_g_OSSL_PARAM_free)(OSSL_PARAM_PTR); +int (*_g_OSSL_PROVIDER_available)(OSSL_LIB_CTX_PTR, const char*); +const char* (*_g_OSSL_PROVIDER_get0_name)(const OSSL_PROVIDER_PTR); +OSSL_PROVIDER_PTR (*_g_OSSL_PROVIDER_try_load)(OSSL_LIB_CTX_PTR, const char*, int); +const char* (*_g_OpenSSL_version)(int); +int (*_g_PKCS5_PBKDF2_HMAC)(const char*, int, const unsigned char*, int, int, const EVP_MD_PTR, int, unsigned char*); +int (*_g_RAND_bytes)(unsigned char*, int); +void (*_g_RSA_free)(RSA_PTR); +void (*_g_RSA_get0_crt_params)(const RSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*, const BIGNUM_PTR*); +void (*_g_RSA_get0_factors)(const RSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*); +void (*_g_RSA_get0_key)(const RSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*, const BIGNUM_PTR*); +RSA_PTR (*_g_RSA_new)(void); +int (*_g_RSA_set0_crt_params)(RSA_PTR, BIGNUM_PTR, BIGNUM_PTR, BIGNUM_PTR); +int (*_g_RSA_set0_factors)(RSA_PTR, BIGNUM_PTR, BIGNUM_PTR); +int (*_g_RSA_set0_key)(RSA_PTR, BIGNUM_PTR, BIGNUM_PTR, BIGNUM_PTR); +int (*_g_SHA1_Final)(unsigned char*, SHA_CTX_PTR); +int (*_g_SHA1_Init)(SHA_CTX_PTR); +int (*_g_SHA1_Update)(SHA_CTX_PTR, const void*, size_t); +const char* (*_g_SSLeay_version)(int); +BIGNUM_PTR (*_g_bn_expand2)(BIGNUM_PTR, int); + +void __mkcgoLoad_crypto(void* handle) { + _g_BN_bin2bn = (BIGNUM_PTR (*)(const unsigned char*, int, BIGNUM_PTR))dlsym(handle, "BN_bin2bn"); + _g_BN_bn2bin = (int (*)(const BIGNUM_PTR, unsigned char*))dlsym(handle, "BN_bn2bin"); + _g_BN_bn2binpad = (int (*)(const BIGNUM_PTR, unsigned char*, int))dlsym(handle, "BN_bn2binpad"); + _g_BN_bn2lebinpad = (int (*)(const BIGNUM_PTR, unsigned char*, int))dlsym(handle, "BN_bn2lebinpad"); + _g_BN_clear = (void (*)(BIGNUM_PTR))dlsym(handle, "BN_clear"); + _g_BN_clear_free = (void (*)(BIGNUM_PTR))dlsym(handle, "BN_clear_free"); + _g_BN_free = (void (*)(BIGNUM_PTR))dlsym(handle, "BN_free"); + _g_BN_lebin2bn = (BIGNUM_PTR (*)(const unsigned char*, int, BIGNUM_PTR))dlsym(handle, "BN_lebin2bn"); + _g_BN_new = (BIGNUM_PTR (*)(void))dlsym(handle, "BN_new"); + _g_BN_num_bits = (int (*)(const BIGNUM_PTR))dlsym(handle, "BN_num_bits"); + _g_CRYPTO_THREADID_set_callback = (int (*)(threadid_func))dlsym(handle, "CRYPTO_THREADID_set_callback"); + _g_CRYPTO_THREADID_set_numeric = (void (*)(CRYPTO_THREADID_PTR, unsigned long))dlsym(handle, "CRYPTO_THREADID_set_numeric"); + _g_CRYPTO_free = (void (*)(void*, const char*, int))dlsym(handle, "CRYPTO_free"); + _g_CRYPTO_malloc = (void* (*)(size_t, const char*, int))dlsym(handle, "CRYPTO_malloc"); + _g_CRYPTO_num_locks = (int (*)(void))dlsym(handle, "CRYPTO_num_locks"); + _g_CRYPTO_set_locking_callback = (void (*)(locking_func))dlsym(handle, "CRYPTO_set_locking_callback"); + _g_DSA_free = (void (*)(DSA_PTR))dlsym(handle, "DSA_free"); + _g_DSA_generate_key = (int (*)(DSA_PTR))dlsym(handle, "DSA_generate_key"); + _g_DSA_get0_key = (void (*)(const DSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*))dlsym(handle, "DSA_get0_key"); + _g_DSA_get0_pqg = (void (*)(const DSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*, const BIGNUM_PTR*))dlsym(handle, "DSA_get0_pqg"); + _g_DSA_new = (DSA_PTR (*)(void))dlsym(handle, "DSA_new"); + _g_DSA_set0_key = (int (*)(DSA_PTR, BIGNUM_PTR, BIGNUM_PTR))dlsym(handle, "DSA_set0_key"); + _g_DSA_set0_pqg = (int (*)(DSA_PTR, BIGNUM_PTR, BIGNUM_PTR, BIGNUM_PTR))dlsym(handle, "DSA_set0_pqg"); + _g_EC_GROUP_free = (void (*)(EC_GROUP_PTR))dlsym(handle, "EC_GROUP_free"); + _g_EC_GROUP_new_by_curve_name = (EC_GROUP_PTR (*)(int))dlsym(handle, "EC_GROUP_new_by_curve_name"); + _g_EC_KEY_free = (void (*)(EC_KEY_PTR))dlsym(handle, "EC_KEY_free"); + _g_EC_KEY_get0_group = (const EC_GROUP_PTR (*)(const EC_KEY_PTR))dlsym(handle, "EC_KEY_get0_group"); + _g_EC_KEY_get0_private_key = (const BIGNUM_PTR (*)(const EC_KEY_PTR))dlsym(handle, "EC_KEY_get0_private_key"); + _g_EC_KEY_get0_public_key = (const EC_POINT_PTR (*)(const EC_KEY_PTR))dlsym(handle, "EC_KEY_get0_public_key"); + _g_EC_KEY_new_by_curve_name = (EC_KEY_PTR (*)(int))dlsym(handle, "EC_KEY_new_by_curve_name"); + _g_EC_KEY_set_private_key = (int (*)(EC_KEY_PTR, const BIGNUM_PTR))dlsym(handle, "EC_KEY_set_private_key"); + _g_EC_KEY_set_public_key = (int (*)(EC_KEY_PTR, const EC_POINT_PTR))dlsym(handle, "EC_KEY_set_public_key"); + _g_EC_KEY_set_public_key_affine_coordinates = (int (*)(EC_KEY_PTR, BIGNUM_PTR, BIGNUM_PTR))dlsym(handle, "EC_KEY_set_public_key_affine_coordinates"); + _g_EC_POINT_free = (void (*)(EC_POINT_PTR))dlsym(handle, "EC_POINT_free"); + _g_EC_POINT_get_affine_coordinates_GFp = (int (*)(const EC_GROUP_PTR, const EC_POINT_PTR, BIGNUM_PTR, BIGNUM_PTR, BN_CTX_PTR))dlsym(handle, "EC_POINT_get_affine_coordinates_GFp"); + _g_EC_POINT_mul = (int (*)(const EC_GROUP_PTR, EC_POINT_PTR, const BIGNUM_PTR, const EC_POINT_PTR, const BIGNUM_PTR, BN_CTX_PTR))dlsym(handle, "EC_POINT_mul"); + _g_EC_POINT_new = (EC_POINT_PTR (*)(const EC_GROUP_PTR))dlsym(handle, "EC_POINT_new"); + _g_EC_POINT_oct2point = (int (*)(const EC_GROUP_PTR, EC_POINT_PTR, const unsigned char*, size_t, BN_CTX_PTR))dlsym(handle, "EC_POINT_oct2point"); + _g_EC_POINT_point2oct = (size_t (*)(const EC_GROUP_PTR, const EC_POINT_PTR, point_conversion_form_t, unsigned char*, size_t, BN_CTX_PTR))dlsym(handle, "EC_POINT_point2oct"); + _g_EC_POINT_set_affine_coordinates = (int (*)(const EC_GROUP_PTR, EC_POINT_PTR, const BIGNUM_PTR, const BIGNUM_PTR, BN_CTX_PTR))dlsym(handle, "EC_POINT_set_affine_coordinates"); + _g_ERR_clear_error = (void (*)(void))dlsym(handle, "ERR_clear_error"); + _g_ERR_error_string_n = (void (*)(unsigned long, char*, size_t))dlsym(handle, "ERR_error_string_n"); + _g_ERR_get_error_all = (unsigned long (*)(const char**, int*, const char**, const char**, int*))dlsym(handle, "ERR_get_error_all"); + _g_ERR_get_error_line = (unsigned long (*)(const char**, int*))dlsym(handle, "ERR_get_error_line"); + _g_ERR_load_crypto_strings = (void (*)(void))dlsym(handle, "ERR_load_crypto_strings"); + _g_ERR_remove_thread_state = (void (*)(const CRYPTO_THREADID_PTR))dlsym(handle, "ERR_remove_thread_state"); + _g_EVP_CIPHER_CTX_ctrl = (int (*)(EVP_CIPHER_CTX_PTR, int, int, void*))dlsym(handle, "EVP_CIPHER_CTX_ctrl"); + _g_EVP_CIPHER_CTX_free = (void (*)(EVP_CIPHER_CTX_PTR))dlsym(handle, "EVP_CIPHER_CTX_free"); + _g_EVP_CIPHER_CTX_new = (EVP_CIPHER_CTX_PTR (*)(void))dlsym(handle, "EVP_CIPHER_CTX_new"); + _g_EVP_CIPHER_CTX_set_key_length = (int (*)(EVP_CIPHER_CTX_PTR, int))dlsym(handle, "EVP_CIPHER_CTX_set_key_length"); + _g_EVP_CIPHER_CTX_set_padding = (int (*)(EVP_CIPHER_CTX_PTR, int))dlsym(handle, "EVP_CIPHER_CTX_set_padding"); + _g_EVP_CIPHER_block_size = (int (*)(const EVP_CIPHER_PTR))dlsym(handle, "EVP_CIPHER_block_size"); + _g_EVP_CIPHER_fetch = (EVP_CIPHER_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*))dlsym(handle, "EVP_CIPHER_fetch"); + _g_EVP_CIPHER_get0_name = (const char* (*)(const EVP_CIPHER_PTR))dlsym(handle, "EVP_CIPHER_get0_name"); + _g_EVP_CIPHER_get_block_size = (int (*)(const EVP_CIPHER_PTR))dlsym(handle, "EVP_CIPHER_get_block_size"); + _g_EVP_CipherInit_ex = (int (*)(EVP_CIPHER_CTX_PTR, const EVP_CIPHER_PTR, ENGINE_PTR, const unsigned char*, const unsigned char*, int))dlsym(handle, "EVP_CipherInit_ex"); + _g_EVP_CipherUpdate = (int (*)(EVP_CIPHER_CTX_PTR, unsigned char*, int*, const unsigned char*, int))dlsym(handle, "EVP_CipherUpdate"); + _g_EVP_DecryptFinal_ex = (int (*)(EVP_CIPHER_CTX_PTR, unsigned char*, int*))dlsym(handle, "EVP_DecryptFinal_ex"); + _g_EVP_DecryptInit_ex = (int (*)(EVP_CIPHER_CTX_PTR, const EVP_CIPHER_PTR, ENGINE_PTR, const unsigned char*, const unsigned char*))dlsym(handle, "EVP_DecryptInit_ex"); + _g_EVP_DecryptUpdate = (int (*)(EVP_CIPHER_CTX_PTR, unsigned char*, int*, const unsigned char*, int))dlsym(handle, "EVP_DecryptUpdate"); + _g_EVP_Digest = (int (*)(const void*, size_t, unsigned char*, unsigned int*, const EVP_MD_PTR, ENGINE_PTR))dlsym(handle, "EVP_Digest"); + _g_EVP_DigestFinal = (int (*)(EVP_MD_CTX_PTR, unsigned char*, unsigned int*))dlsym(handle, "EVP_DigestFinal"); + _g_EVP_DigestInit = (int (*)(EVP_MD_CTX_PTR, const EVP_MD_PTR))dlsym(handle, "EVP_DigestInit"); + _g_EVP_DigestInit_ex = (int (*)(EVP_MD_CTX_PTR, const EVP_MD_PTR, ENGINE_PTR))dlsym(handle, "EVP_DigestInit_ex"); + _g_EVP_DigestSign = (int (*)(EVP_MD_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t))dlsym(handle, "EVP_DigestSign"); + _g_EVP_DigestSignFinal = (int (*)(EVP_MD_CTX_PTR, unsigned char*, size_t*))dlsym(handle, "EVP_DigestSignFinal"); + _g_EVP_DigestSignInit = (int (*)(EVP_MD_CTX_PTR, EVP_PKEY_CTX_PTR*, const EVP_MD_PTR, ENGINE_PTR, EVP_PKEY_PTR))dlsym(handle, "EVP_DigestSignInit"); + _g_EVP_DigestUpdate = (int (*)(EVP_MD_CTX_PTR, const void*, size_t))dlsym(handle, "EVP_DigestUpdate"); + _g_EVP_DigestVerify = (int (*)(EVP_MD_CTX_PTR, const unsigned char*, size_t, const unsigned char*, size_t))dlsym(handle, "EVP_DigestVerify"); + _g_EVP_DigestVerifyFinal = (int (*)(EVP_MD_CTX_PTR, const unsigned char*, size_t))dlsym(handle, "EVP_DigestVerifyFinal"); + _g_EVP_DigestVerifyInit = (int (*)(EVP_MD_CTX_PTR, EVP_PKEY_CTX_PTR*, const EVP_MD_PTR, ENGINE_PTR, EVP_PKEY_PTR))dlsym(handle, "EVP_DigestVerifyInit"); + _g_EVP_EncryptFinal_ex = (int (*)(EVP_CIPHER_CTX_PTR, unsigned char*, int*))dlsym(handle, "EVP_EncryptFinal_ex"); + _g_EVP_EncryptInit_ex = (int (*)(EVP_CIPHER_CTX_PTR, const EVP_CIPHER_PTR, ENGINE_PTR, const unsigned char*, const unsigned char*))dlsym(handle, "EVP_EncryptInit_ex"); + _g_EVP_EncryptUpdate = (int (*)(EVP_CIPHER_CTX_PTR, unsigned char*, int*, const unsigned char*, int))dlsym(handle, "EVP_EncryptUpdate"); + _g_EVP_KDF_CTX_free = (void (*)(EVP_KDF_CTX_PTR))dlsym(handle, "EVP_KDF_CTX_free"); + _g_EVP_KDF_CTX_get_kdf_size = (size_t (*)(EVP_KDF_CTX_PTR))dlsym(handle, "EVP_KDF_CTX_get_kdf_size"); + _g_EVP_KDF_CTX_new = (EVP_KDF_CTX_PTR (*)(EVP_KDF_PTR))dlsym(handle, "EVP_KDF_CTX_new"); + _g_EVP_KDF_CTX_set_params = (int (*)(EVP_KDF_CTX_PTR, const OSSL_PARAM_PTR))dlsym(handle, "EVP_KDF_CTX_set_params"); + _g_EVP_KDF_derive = (int (*)(EVP_KDF_CTX_PTR, unsigned char*, size_t, const OSSL_PARAM_PTR))dlsym(handle, "EVP_KDF_derive"); + _g_EVP_KDF_fetch = (EVP_KDF_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*))dlsym(handle, "EVP_KDF_fetch"); + _g_EVP_KDF_free = (void (*)(EVP_KDF_PTR))dlsym(handle, "EVP_KDF_free"); + _g_EVP_MAC_CTX_dup = (EVP_MAC_CTX_PTR (*)(const EVP_MAC_CTX_PTR))dlsym(handle, "EVP_MAC_CTX_dup"); + _g_EVP_MAC_CTX_free = (void (*)(EVP_MAC_CTX_PTR))dlsym(handle, "EVP_MAC_CTX_free"); + _g_EVP_MAC_CTX_new = (EVP_MAC_CTX_PTR (*)(EVP_MAC_PTR))dlsym(handle, "EVP_MAC_CTX_new"); + _g_EVP_MAC_CTX_set_params = (int (*)(EVP_MAC_CTX_PTR, const OSSL_PARAM_PTR))dlsym(handle, "EVP_MAC_CTX_set_params"); + _g_EVP_MAC_fetch = (EVP_MAC_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*))dlsym(handle, "EVP_MAC_fetch"); + _g_EVP_MAC_final = (int (*)(EVP_MAC_CTX_PTR, unsigned char*, size_t*, size_t))dlsym(handle, "EVP_MAC_final"); + _g_EVP_MAC_init = (int (*)(EVP_MAC_CTX_PTR, const unsigned char*, size_t, const OSSL_PARAM_PTR))dlsym(handle, "EVP_MAC_init"); + _g_EVP_MAC_update = (int (*)(EVP_MAC_CTX_PTR, const unsigned char*, size_t))dlsym(handle, "EVP_MAC_update"); + _g_EVP_MD_CTX_copy = (int (*)(EVP_MD_CTX_PTR, const EVP_MD_CTX_PTR))dlsym(handle, "EVP_MD_CTX_copy"); + _g_EVP_MD_CTX_copy_ex = (int (*)(EVP_MD_CTX_PTR, const EVP_MD_CTX_PTR))dlsym(handle, "EVP_MD_CTX_copy_ex"); + _g_EVP_MD_CTX_create = (EVP_MD_CTX_PTR (*)(void))dlsym(handle, "EVP_MD_CTX_create"); + _g_EVP_MD_CTX_destroy = (void (*)(EVP_MD_CTX_PTR))dlsym(handle, "EVP_MD_CTX_destroy"); + _g_EVP_MD_CTX_free = (void (*)(EVP_MD_CTX_PTR))dlsym(handle, "EVP_MD_CTX_free"); + _g_EVP_MD_CTX_new = (EVP_MD_CTX_PTR (*)(void))dlsym(handle, "EVP_MD_CTX_new"); + _g_EVP_MD_block_size = (int (*)(const EVP_MD_PTR))dlsym(handle, "EVP_MD_block_size"); + _g_EVP_MD_fetch = (EVP_MD_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*))dlsym(handle, "EVP_MD_fetch"); + _g_EVP_MD_free = (void (*)(EVP_MD_PTR))dlsym(handle, "EVP_MD_free"); + _g_EVP_MD_get0_name = (const char* (*)(const EVP_MD_PTR))dlsym(handle, "EVP_MD_get0_name"); + _g_EVP_MD_get0_provider = (const OSSL_PROVIDER_PTR (*)(const EVP_MD_PTR))dlsym(handle, "EVP_MD_get0_provider"); + _g_EVP_MD_get_block_size = (int (*)(const EVP_MD_PTR))dlsym(handle, "EVP_MD_get_block_size"); + _g_EVP_MD_get_size = (int (*)(const EVP_MD_PTR))dlsym(handle, "EVP_MD_get_size"); + _g_EVP_MD_size = (int (*)(const EVP_MD_PTR))dlsym(handle, "EVP_MD_size"); + _g_EVP_PKEY_CTX_add1_hkdf_info = (int (*)(EVP_PKEY_CTX_PTR, const unsigned char*, int))dlsym(handle, "EVP_PKEY_CTX_add1_hkdf_info"); + _g_EVP_PKEY_CTX_ctrl = (int (*)(EVP_PKEY_CTX_PTR, int, int, int, int, void*))dlsym(handle, "EVP_PKEY_CTX_ctrl"); + _g_EVP_PKEY_CTX_free = (void (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_CTX_free"); + _g_EVP_PKEY_CTX_new = (EVP_PKEY_CTX_PTR (*)(EVP_PKEY_PTR, ENGINE_PTR))dlsym(handle, "EVP_PKEY_CTX_new"); + _g_EVP_PKEY_CTX_new_from_pkey = (EVP_PKEY_CTX_PTR (*)(OSSL_LIB_CTX_PTR, EVP_PKEY_PTR, const char*))dlsym(handle, "EVP_PKEY_CTX_new_from_pkey"); + _g_EVP_PKEY_CTX_new_id = (EVP_PKEY_CTX_PTR (*)(int, ENGINE_PTR))dlsym(handle, "EVP_PKEY_CTX_new_id"); + _g_EVP_PKEY_CTX_set0_rsa_oaep_label = (int (*)(EVP_PKEY_CTX_PTR, void*, int))dlsym(handle, "EVP_PKEY_CTX_set0_rsa_oaep_label"); + _g_EVP_PKEY_CTX_set1_hkdf_key = (int (*)(EVP_PKEY_CTX_PTR, const unsigned char*, int))dlsym(handle, "EVP_PKEY_CTX_set1_hkdf_key"); + _g_EVP_PKEY_CTX_set1_hkdf_salt = (int (*)(EVP_PKEY_CTX_PTR, const unsigned char*, int))dlsym(handle, "EVP_PKEY_CTX_set1_hkdf_salt"); + _g_EVP_PKEY_CTX_set_hkdf_md = (int (*)(EVP_PKEY_CTX_PTR, const EVP_MD_PTR))dlsym(handle, "EVP_PKEY_CTX_set_hkdf_md"); + _g_EVP_PKEY_CTX_set_hkdf_mode = (int (*)(EVP_PKEY_CTX_PTR, int))dlsym(handle, "EVP_PKEY_CTX_set_hkdf_mode"); + _g_EVP_PKEY_Q_keygen_EC = (EVP_PKEY_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*, const char*))dlsym(handle, "EVP_PKEY_Q_keygen"); + _g_EVP_PKEY_Q_keygen_ED25519 = (EVP_PKEY_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*))dlsym(handle, "EVP_PKEY_Q_keygen"); + _g_EVP_PKEY_Q_keygen_RSA = (EVP_PKEY_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*, size_t))dlsym(handle, "EVP_PKEY_Q_keygen"); + _g_EVP_PKEY_assign = (int (*)(EVP_PKEY_PTR, int, void*))dlsym(handle, "EVP_PKEY_assign"); + _g_EVP_PKEY_bits = (int (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_bits"); + _g_EVP_PKEY_decrypt = (int (*)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_decrypt"); + _g_EVP_PKEY_decrypt_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_decrypt_init"); + _g_EVP_PKEY_derive = (int (*)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*))dlsym(handle, "EVP_PKEY_derive"); + _g_EVP_PKEY_derive_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_derive_init"); + _g_EVP_PKEY_derive_set_peer = (int (*)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_derive_set_peer"); + _g_EVP_PKEY_encrypt = (int (*)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_encrypt"); + _g_EVP_PKEY_encrypt_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_encrypt_init"); + _g_EVP_PKEY_free = (void (*)(EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_free"); + _g_EVP_PKEY_fromdata = (int (*)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR*, int, OSSL_PARAM_PTR))dlsym(handle, "EVP_PKEY_fromdata"); + _g_EVP_PKEY_fromdata_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_fromdata_init"); + _g_EVP_PKEY_get0 = (void* (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_get0"); + _g_EVP_PKEY_get0_DSA = (const DSA_PTR (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_get0_DSA"); + _g_EVP_PKEY_get0_EC_KEY = (const EC_KEY_PTR (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_get0_EC_KEY"); + _g_EVP_PKEY_get1_RSA = (RSA_PTR (*)(EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_get1_RSA"); + _g_EVP_PKEY_get1_encoded_public_key = (size_t (*)(EVP_PKEY_PTR, unsigned char**))dlsym(handle, "EVP_PKEY_get1_encoded_public_key"); + _g_EVP_PKEY_get_bits = (int (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_get_bits"); + _g_EVP_PKEY_get_bn_param = (int (*)(const EVP_PKEY_PTR, const char*, BIGNUM_PTR*))dlsym(handle, "EVP_PKEY_get_bn_param"); + _g_EVP_PKEY_get_raw_private_key = (int (*)(const EVP_PKEY_PTR, unsigned char*, size_t*))dlsym(handle, "EVP_PKEY_get_raw_private_key"); + _g_EVP_PKEY_get_raw_public_key = (int (*)(const EVP_PKEY_PTR, unsigned char*, size_t*))dlsym(handle, "EVP_PKEY_get_raw_public_key"); + _g_EVP_PKEY_get_size = (int (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_get_size"); + _g_EVP_PKEY_keygen = (int (*)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR*))dlsym(handle, "EVP_PKEY_keygen"); + _g_EVP_PKEY_keygen_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_keygen_init"); + _g_EVP_PKEY_new = (EVP_PKEY_PTR (*)(void))dlsym(handle, "EVP_PKEY_new"); + _g_EVP_PKEY_new_raw_private_key = (EVP_PKEY_PTR (*)(int, ENGINE_PTR, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_new_raw_private_key"); + _g_EVP_PKEY_new_raw_public_key = (EVP_PKEY_PTR (*)(int, ENGINE_PTR, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_new_raw_public_key"); + _g_EVP_PKEY_paramgen = (int (*)(EVP_PKEY_CTX_PTR, EVP_PKEY_PTR*))dlsym(handle, "EVP_PKEY_paramgen"); + _g_EVP_PKEY_paramgen_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_paramgen_init"); + _g_EVP_PKEY_set1_EC_KEY = (int (*)(EVP_PKEY_PTR, EC_KEY_PTR))dlsym(handle, "EVP_PKEY_set1_EC_KEY"); + _g_EVP_PKEY_set1_encoded_public_key = (int (*)(EVP_PKEY_PTR, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_set1_encoded_public_key"); + _g_EVP_PKEY_sign = (int (*)(EVP_PKEY_CTX_PTR, unsigned char*, size_t*, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_sign"); + _g_EVP_PKEY_sign_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_sign_init"); + _g_EVP_PKEY_size = (int (*)(const EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_size"); + _g_EVP_PKEY_up_ref = (int (*)(EVP_PKEY_PTR))dlsym(handle, "EVP_PKEY_up_ref"); + _g_EVP_PKEY_verify = (int (*)(EVP_PKEY_CTX_PTR, const unsigned char*, size_t, const unsigned char*, size_t))dlsym(handle, "EVP_PKEY_verify"); + _g_EVP_PKEY_verify_init = (int (*)(EVP_PKEY_CTX_PTR))dlsym(handle, "EVP_PKEY_verify_init"); + _g_EVP_SIGNATURE_fetch = (EVP_SIGNATURE_PTR (*)(OSSL_LIB_CTX_PTR, const char*, const char*))dlsym(handle, "EVP_SIGNATURE_fetch"); + _g_EVP_SIGNATURE_free = (void (*)(EVP_SIGNATURE_PTR))dlsym(handle, "EVP_SIGNATURE_free"); + _g_EVP_aes_128_cbc = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_128_cbc"); + _g_EVP_aes_128_ctr = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_128_ctr"); + _g_EVP_aes_128_ecb = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_128_ecb"); + _g_EVP_aes_128_gcm = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_128_gcm"); + _g_EVP_aes_192_cbc = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_192_cbc"); + _g_EVP_aes_192_ctr = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_192_ctr"); + _g_EVP_aes_192_ecb = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_192_ecb"); + _g_EVP_aes_192_gcm = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_192_gcm"); + _g_EVP_aes_256_cbc = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_256_cbc"); + _g_EVP_aes_256_ctr = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_256_ctr"); + _g_EVP_aes_256_ecb = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_256_ecb"); + _g_EVP_aes_256_gcm = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_aes_256_gcm"); + _g_EVP_default_properties_enable_fips = (int (*)(OSSL_LIB_CTX_PTR, int))dlsym(handle, "EVP_default_properties_enable_fips"); + _g_EVP_default_properties_is_fips_enabled = (int (*)(OSSL_LIB_CTX_PTR))dlsym(handle, "EVP_default_properties_is_fips_enabled"); + _g_EVP_des_cbc = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_des_cbc"); + _g_EVP_des_ecb = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_des_ecb"); + _g_EVP_des_ede3_cbc = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_des_ede3_cbc"); + _g_EVP_des_ede3_ecb = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_des_ede3_ecb"); + _g_EVP_md4 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_md4"); + _g_EVP_md5 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_md5"); + _g_EVP_md5_sha1 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_md5_sha1"); + _g_EVP_rc4 = (EVP_CIPHER_PTR (*)(void))dlsym(handle, "EVP_rc4"); + _g_EVP_sha1 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha1"); + _g_EVP_sha224 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha224"); + _g_EVP_sha256 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha256"); + _g_EVP_sha384 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha384"); + _g_EVP_sha3_224 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha3_224"); + _g_EVP_sha3_256 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha3_256"); + _g_EVP_sha3_384 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha3_384"); + _g_EVP_sha3_512 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha3_512"); + _g_EVP_sha512 = (const EVP_MD_PTR (*)(void))dlsym(handle, "EVP_sha512"); + _g_FIPS_mode = (int (*)(void))dlsym(handle, "FIPS_mode"); + _g_FIPS_mode_set = (int (*)(int))dlsym(handle, "FIPS_mode_set"); + _g_HMAC_CTX_cleanup = (void (*)(HMAC_CTX_PTR))dlsym(handle, "HMAC_CTX_cleanup"); + _g_HMAC_CTX_copy = (int (*)(HMAC_CTX_PTR, HMAC_CTX_PTR))dlsym(handle, "HMAC_CTX_copy"); + _g_HMAC_CTX_free = (void (*)(HMAC_CTX_PTR))dlsym(handle, "HMAC_CTX_free"); + _g_HMAC_CTX_init = (void (*)(HMAC_CTX_PTR))dlsym(handle, "HMAC_CTX_init"); + _g_HMAC_CTX_new = (HMAC_CTX_PTR (*)(void))dlsym(handle, "HMAC_CTX_new"); + _g_HMAC_Final = (int (*)(HMAC_CTX_PTR, unsigned char*, unsigned int*))dlsym(handle, "HMAC_Final"); + _g_HMAC_Init_ex = (int (*)(HMAC_CTX_PTR, const void*, int, const EVP_MD_PTR, ENGINE_PTR))dlsym(handle, "HMAC_Init_ex"); + _g_HMAC_Update = (int (*)(HMAC_CTX_PTR, const unsigned char*, size_t))dlsym(handle, "HMAC_Update"); + _g_MD5_Final = (int (*)(unsigned char*, MD5_CTX_PTR))dlsym(handle, "MD5_Final"); + _g_MD5_Init = (int (*)(MD5_CTX_PTR))dlsym(handle, "MD5_Init"); + _g_MD5_Update = (int (*)(MD5_CTX_PTR, const void*, size_t))dlsym(handle, "MD5_Update"); + _g_OBJ_nid2sn = (const char* (*)(int))dlsym(handle, "OBJ_nid2sn"); + _g_OPENSSL_add_all_algorithms_conf = (void (*)(void))dlsym(handle, "OPENSSL_add_all_algorithms_conf"); + _g_OPENSSL_init = (void (*)(void))dlsym(handle, "OPENSSL_init"); + _g_OPENSSL_init_crypto = (int (*)(uint64_t, const OPENSSL_INIT_SETTINGS_PTR))dlsym(handle, "OPENSSL_init_crypto"); + _g_OSSL_PARAM_BLD_free = (void (*)(OSSL_PARAM_BLD_PTR))dlsym(handle, "OSSL_PARAM_BLD_free"); + _g_OSSL_PARAM_BLD_new = (OSSL_PARAM_BLD_PTR (*)(void))dlsym(handle, "OSSL_PARAM_BLD_new"); + _g_OSSL_PARAM_BLD_push_BN = (int (*)(OSSL_PARAM_BLD_PTR, const char*, const BIGNUM_PTR))dlsym(handle, "OSSL_PARAM_BLD_push_BN"); + _g_OSSL_PARAM_BLD_push_int32 = (int (*)(OSSL_PARAM_BLD_PTR, const char*, int32_t))dlsym(handle, "OSSL_PARAM_BLD_push_int32"); + _g_OSSL_PARAM_BLD_push_octet_string = (int (*)(OSSL_PARAM_BLD_PTR, const char*, const void*, size_t))dlsym(handle, "OSSL_PARAM_BLD_push_octet_string"); + _g_OSSL_PARAM_BLD_push_utf8_string = (int (*)(OSSL_PARAM_BLD_PTR, const char*, const char*, size_t))dlsym(handle, "OSSL_PARAM_BLD_push_utf8_string"); + _g_OSSL_PARAM_BLD_to_param = (OSSL_PARAM_PTR (*)(OSSL_PARAM_BLD_PTR))dlsym(handle, "OSSL_PARAM_BLD_to_param"); + _g_OSSL_PARAM_free = (void (*)(OSSL_PARAM_PTR))dlsym(handle, "OSSL_PARAM_free"); + _g_OSSL_PROVIDER_available = (int (*)(OSSL_LIB_CTX_PTR, const char*))dlsym(handle, "OSSL_PROVIDER_available"); + _g_OSSL_PROVIDER_get0_name = (const char* (*)(const OSSL_PROVIDER_PTR))dlsym(handle, "OSSL_PROVIDER_get0_name"); + _g_OSSL_PROVIDER_try_load = (OSSL_PROVIDER_PTR (*)(OSSL_LIB_CTX_PTR, const char*, int))dlsym(handle, "OSSL_PROVIDER_try_load"); + _g_OpenSSL_version = (const char* (*)(int))dlsym(handle, "OpenSSL_version"); + _g_PKCS5_PBKDF2_HMAC = (int (*)(const char*, int, const unsigned char*, int, int, const EVP_MD_PTR, int, unsigned char*))dlsym(handle, "PKCS5_PBKDF2_HMAC"); + _g_RAND_bytes = (int (*)(unsigned char*, int))dlsym(handle, "RAND_bytes"); + _g_RSA_free = (void (*)(RSA_PTR))dlsym(handle, "RSA_free"); + _g_RSA_get0_crt_params = (void (*)(const RSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*, const BIGNUM_PTR*))dlsym(handle, "RSA_get0_crt_params"); + _g_RSA_get0_factors = (void (*)(const RSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*))dlsym(handle, "RSA_get0_factors"); + _g_RSA_get0_key = (void (*)(const RSA_PTR, const BIGNUM_PTR*, const BIGNUM_PTR*, const BIGNUM_PTR*))dlsym(handle, "RSA_get0_key"); + _g_RSA_new = (RSA_PTR (*)(void))dlsym(handle, "RSA_new"); + _g_RSA_set0_crt_params = (int (*)(RSA_PTR, BIGNUM_PTR, BIGNUM_PTR, BIGNUM_PTR))dlsym(handle, "RSA_set0_crt_params"); + _g_RSA_set0_factors = (int (*)(RSA_PTR, BIGNUM_PTR, BIGNUM_PTR))dlsym(handle, "RSA_set0_factors"); + _g_RSA_set0_key = (int (*)(RSA_PTR, BIGNUM_PTR, BIGNUM_PTR, BIGNUM_PTR))dlsym(handle, "RSA_set0_key"); + _g_SHA1_Final = (int (*)(unsigned char*, SHA_CTX_PTR))dlsym(handle, "SHA1_Final"); + _g_SHA1_Init = (int (*)(SHA_CTX_PTR))dlsym(handle, "SHA1_Init"); + _g_SHA1_Update = (int (*)(SHA_CTX_PTR, const void*, size_t))dlsym(handle, "SHA1_Update"); + _g_SSLeay_version = (const char* (*)(int))dlsym(handle, "SSLeay_version"); + _g_bn_expand2 = (BIGNUM_PTR (*)(BIGNUM_PTR, int))dlsym(handle, "bn_expand2"); +} + +BIGNUM_PTR BN_bin2bn(const unsigned char* _arg0, int _arg1, BIGNUM_PTR _arg2) { + return _g_BN_bin2bn(_arg0, _arg1, _arg2); +} + +int BN_bn2bin(const BIGNUM_PTR _arg0, unsigned char* _arg1) { + return _g_BN_bn2bin(_arg0, _arg1); +} + +int BN_bn2binpad(const BIGNUM_PTR _arg0, unsigned char* _arg1, int _arg2) { + return _g_BN_bn2binpad(_arg0, _arg1, _arg2); +} + +int BN_bn2lebinpad(const BIGNUM_PTR _arg0, unsigned char* _arg1, int _arg2) { + return _g_BN_bn2lebinpad(_arg0, _arg1, _arg2); +} + +void BN_clear(BIGNUM_PTR _arg0) { + _g_BN_clear(_arg0); +} + +void BN_clear_free(BIGNUM_PTR _arg0) { + _g_BN_clear_free(_arg0); +} + +void BN_free(BIGNUM_PTR _arg0) { + _g_BN_free(_arg0); +} + +BIGNUM_PTR BN_lebin2bn(const unsigned char* _arg0, int _arg1, BIGNUM_PTR _arg2) { + return _g_BN_lebin2bn(_arg0, _arg1, _arg2); +} + +BIGNUM_PTR BN_new(void) { + return _g_BN_new(); +} + +int BN_num_bits(const BIGNUM_PTR _arg0) { + return _g_BN_num_bits(_arg0); +} + +int CRYPTO_THREADID_set_callback(threadid_func _arg0) { + return _g_CRYPTO_THREADID_set_callback(_arg0); +} + +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID_PTR _arg0, unsigned long _arg1) { + _g_CRYPTO_THREADID_set_numeric(_arg0, _arg1); +} + +void CRYPTO_free(void* _arg0, const char* _arg1, int _arg2) { + _g_CRYPTO_free(_arg0, _arg1, _arg2); +} + +void* CRYPTO_malloc(size_t _arg0, const char* _arg1, int _arg2) { + return _g_CRYPTO_malloc(_arg0, _arg1, _arg2); +} + +int CRYPTO_num_locks(void) { + return _g_CRYPTO_num_locks(); +} + +void CRYPTO_set_locking_callback(locking_func _arg0) { + _g_CRYPTO_set_locking_callback(_arg0); +} + +void DSA_free(DSA_PTR _arg0) { + _g_DSA_free(_arg0); +} + +int DSA_generate_key(DSA_PTR _arg0) { + return _g_DSA_generate_key(_arg0); +} + +void DSA_get0_key(const DSA_PTR _arg0, const BIGNUM_PTR* _arg1, const BIGNUM_PTR* _arg2) { + _g_DSA_get0_key(_arg0, _arg1, _arg2); +} + +void DSA_get0_pqg(const DSA_PTR _arg0, const BIGNUM_PTR* _arg1, const BIGNUM_PTR* _arg2, const BIGNUM_PTR* _arg3) { + _g_DSA_get0_pqg(_arg0, _arg1, _arg2, _arg3); +} + +DSA_PTR DSA_new(void) { + return _g_DSA_new(); +} + +int DSA_set0_key(DSA_PTR _arg0, BIGNUM_PTR _arg1, BIGNUM_PTR _arg2) { + return _g_DSA_set0_key(_arg0, _arg1, _arg2); +} + +int DSA_set0_pqg(DSA_PTR _arg0, BIGNUM_PTR _arg1, BIGNUM_PTR _arg2, BIGNUM_PTR _arg3) { + return _g_DSA_set0_pqg(_arg0, _arg1, _arg2, _arg3); +} + +void EC_GROUP_free(EC_GROUP_PTR _arg0) { + _g_EC_GROUP_free(_arg0); +} + +EC_GROUP_PTR EC_GROUP_new_by_curve_name(int _arg0) { + return _g_EC_GROUP_new_by_curve_name(_arg0); +} + +void EC_KEY_free(EC_KEY_PTR _arg0) { + _g_EC_KEY_free(_arg0); +} + +const EC_GROUP_PTR EC_KEY_get0_group(const EC_KEY_PTR _arg0) { + return _g_EC_KEY_get0_group(_arg0); +} + +const BIGNUM_PTR EC_KEY_get0_private_key(const EC_KEY_PTR _arg0) { + return _g_EC_KEY_get0_private_key(_arg0); +} + +const EC_POINT_PTR EC_KEY_get0_public_key(const EC_KEY_PTR _arg0) { + return _g_EC_KEY_get0_public_key(_arg0); +} + +EC_KEY_PTR EC_KEY_new_by_curve_name(int _arg0) { + return _g_EC_KEY_new_by_curve_name(_arg0); +} + +int EC_KEY_set_private_key(EC_KEY_PTR _arg0, const BIGNUM_PTR _arg1) { + return _g_EC_KEY_set_private_key(_arg0, _arg1); +} + +int EC_KEY_set_public_key(EC_KEY_PTR _arg0, const EC_POINT_PTR _arg1) { + return _g_EC_KEY_set_public_key(_arg0, _arg1); +} + +int EC_KEY_set_public_key_affine_coordinates(EC_KEY_PTR _arg0, BIGNUM_PTR _arg1, BIGNUM_PTR _arg2) { + return _g_EC_KEY_set_public_key_affine_coordinates(_arg0, _arg1, _arg2); +} + +void EC_POINT_free(EC_POINT_PTR _arg0) { + _g_EC_POINT_free(_arg0); +} + +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP_PTR _arg0, const EC_POINT_PTR _arg1, BIGNUM_PTR _arg2, BIGNUM_PTR _arg3, BN_CTX_PTR _arg4) { + return _g_EC_POINT_get_affine_coordinates_GFp(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EC_POINT_mul(const EC_GROUP_PTR _arg0, EC_POINT_PTR _arg1, const BIGNUM_PTR _arg2, const EC_POINT_PTR _arg3, const BIGNUM_PTR _arg4, BN_CTX_PTR _arg5) { + return _g_EC_POINT_mul(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); +} + +EC_POINT_PTR EC_POINT_new(const EC_GROUP_PTR _arg0) { + return _g_EC_POINT_new(_arg0); +} + +int EC_POINT_oct2point(const EC_GROUP_PTR _arg0, EC_POINT_PTR _arg1, const unsigned char* _arg2, size_t _arg3, BN_CTX_PTR _arg4) { + return _g_EC_POINT_oct2point(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +size_t EC_POINT_point2oct(const EC_GROUP_PTR _arg0, const EC_POINT_PTR _arg1, point_conversion_form_t _arg2, unsigned char* _arg3, size_t _arg4, BN_CTX_PTR _arg5) { + return _g_EC_POINT_point2oct(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); +} + +int EC_POINT_set_affine_coordinates(const EC_GROUP_PTR _arg0, EC_POINT_PTR _arg1, const BIGNUM_PTR _arg2, const BIGNUM_PTR _arg3, BN_CTX_PTR _arg4) { + return _g_EC_POINT_set_affine_coordinates(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +void ERR_clear_error(void) { + _g_ERR_clear_error(); +} + +void ERR_error_string_n(unsigned long _arg0, char* _arg1, size_t _arg2) { + _g_ERR_error_string_n(_arg0, _arg1, _arg2); +} + +unsigned long ERR_get_error_all(const char** _arg0, int* _arg1, const char** _arg2, const char** _arg3, int* _arg4) { + return _g_ERR_get_error_all(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +unsigned long ERR_get_error_line(const char** _arg0, int* _arg1) { + return _g_ERR_get_error_line(_arg0, _arg1); +} + +void ERR_load_crypto_strings(void) { + _g_ERR_load_crypto_strings(); +} + +void ERR_remove_thread_state(const CRYPTO_THREADID_PTR _arg0) { + _g_ERR_remove_thread_state(_arg0); +} + +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX_PTR _arg0, int _arg1, int _arg2, void* _arg3) { + return _g_EVP_CIPHER_CTX_ctrl(_arg0, _arg1, _arg2, _arg3); +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX_PTR _arg0) { + _g_EVP_CIPHER_CTX_free(_arg0); +} + +EVP_CIPHER_CTX_PTR EVP_CIPHER_CTX_new(void) { + return _g_EVP_CIPHER_CTX_new(); +} + +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX_PTR _arg0, int _arg1) { + return _g_EVP_CIPHER_CTX_set_key_length(_arg0, _arg1); +} + +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX_PTR _arg0, int _arg1) { + return _g_EVP_CIPHER_CTX_set_padding(_arg0, _arg1); +} + +int EVP_CIPHER_block_size(const EVP_CIPHER_PTR _arg0) { + return _g_EVP_CIPHER_block_size(_arg0); +} + +EVP_CIPHER_PTR EVP_CIPHER_fetch(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2) { + return _g_EVP_CIPHER_fetch(_arg0, _arg1, _arg2); +} + +const char* EVP_CIPHER_get0_name(const EVP_CIPHER_PTR _arg0) { + return _g_EVP_CIPHER_get0_name(_arg0); +} + +int EVP_CIPHER_get_block_size(const EVP_CIPHER_PTR _arg0) { + return _g_EVP_CIPHER_get_block_size(_arg0); +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX_PTR _arg0, const EVP_CIPHER_PTR _arg1, ENGINE_PTR _arg2, const unsigned char* _arg3, const unsigned char* _arg4, int _arg5) { + return _g_EVP_CipherInit_ex(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); +} + +int EVP_CipherUpdate(EVP_CIPHER_CTX_PTR _arg0, unsigned char* _arg1, int* _arg2, const unsigned char* _arg3, int _arg4) { + return _g_EVP_CipherUpdate(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX_PTR _arg0, unsigned char* _arg1, int* _arg2) { + return _g_EVP_DecryptFinal_ex(_arg0, _arg1, _arg2); +} + +int EVP_DecryptInit_ex(EVP_CIPHER_CTX_PTR _arg0, const EVP_CIPHER_PTR _arg1, ENGINE_PTR _arg2, const unsigned char* _arg3, const unsigned char* _arg4) { + return _g_EVP_DecryptInit_ex(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_DecryptUpdate(EVP_CIPHER_CTX_PTR _arg0, unsigned char* _arg1, int* _arg2, const unsigned char* _arg3, int _arg4) { + return _g_EVP_DecryptUpdate(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_Digest(const void* _arg0, size_t _arg1, unsigned char* _arg2, unsigned int* _arg3, const EVP_MD_PTR _arg4, ENGINE_PTR _arg5) { + return _g_EVP_Digest(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); +} + +int EVP_DigestFinal(EVP_MD_CTX_PTR _arg0, unsigned char* _arg1, unsigned int* _arg2) { + return _g_EVP_DigestFinal(_arg0, _arg1, _arg2); +} + +int EVP_DigestInit(EVP_MD_CTX_PTR _arg0, const EVP_MD_PTR _arg1) { + return _g_EVP_DigestInit(_arg0, _arg1); +} + +int EVP_DigestInit_ex(EVP_MD_CTX_PTR _arg0, const EVP_MD_PTR _arg1, ENGINE_PTR _arg2) { + return _g_EVP_DigestInit_ex(_arg0, _arg1, _arg2); +} + +int EVP_DigestSign(EVP_MD_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2, const unsigned char* _arg3, size_t _arg4) { + return _g_EVP_DigestSign(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_DigestSignFinal(EVP_MD_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2) { + return _g_EVP_DigestSignFinal(_arg0, _arg1, _arg2); +} + +int EVP_DigestSignInit(EVP_MD_CTX_PTR _arg0, EVP_PKEY_CTX_PTR* _arg1, const EVP_MD_PTR _arg2, ENGINE_PTR _arg3, EVP_PKEY_PTR _arg4) { + return _g_EVP_DigestSignInit(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_DigestUpdate(EVP_MD_CTX_PTR _arg0, const void* _arg1, size_t _arg2) { + return _g_EVP_DigestUpdate(_arg0, _arg1, _arg2); +} + +int EVP_DigestVerify(EVP_MD_CTX_PTR _arg0, const unsigned char* _arg1, size_t _arg2, const unsigned char* _arg3, size_t _arg4) { + return _g_EVP_DigestVerify(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_DigestVerifyFinal(EVP_MD_CTX_PTR _arg0, const unsigned char* _arg1, size_t _arg2) { + return _g_EVP_DigestVerifyFinal(_arg0, _arg1, _arg2); +} + +int EVP_DigestVerifyInit(EVP_MD_CTX_PTR _arg0, EVP_PKEY_CTX_PTR* _arg1, const EVP_MD_PTR _arg2, ENGINE_PTR _arg3, EVP_PKEY_PTR _arg4) { + return _g_EVP_DigestVerifyInit(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX_PTR _arg0, unsigned char* _arg1, int* _arg2) { + return _g_EVP_EncryptFinal_ex(_arg0, _arg1, _arg2); +} + +int EVP_EncryptInit_ex(EVP_CIPHER_CTX_PTR _arg0, const EVP_CIPHER_PTR _arg1, ENGINE_PTR _arg2, const unsigned char* _arg3, const unsigned char* _arg4) { + return _g_EVP_EncryptInit_ex(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_EncryptUpdate(EVP_CIPHER_CTX_PTR _arg0, unsigned char* _arg1, int* _arg2, const unsigned char* _arg3, int _arg4) { + return _g_EVP_EncryptUpdate(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +void EVP_KDF_CTX_free(EVP_KDF_CTX_PTR _arg0) { + _g_EVP_KDF_CTX_free(_arg0); +} + +size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX_PTR _arg0) { + return _g_EVP_KDF_CTX_get_kdf_size(_arg0); +} + +EVP_KDF_CTX_PTR EVP_KDF_CTX_new(EVP_KDF_PTR _arg0) { + return _g_EVP_KDF_CTX_new(_arg0); +} + +int EVP_KDF_CTX_set_params(EVP_KDF_CTX_PTR _arg0, const OSSL_PARAM_PTR _arg1) { + return _g_EVP_KDF_CTX_set_params(_arg0, _arg1); +} + +int EVP_KDF_derive(EVP_KDF_CTX_PTR _arg0, unsigned char* _arg1, size_t _arg2, const OSSL_PARAM_PTR _arg3) { + return _g_EVP_KDF_derive(_arg0, _arg1, _arg2, _arg3); +} + +EVP_KDF_PTR EVP_KDF_fetch(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2) { + return _g_EVP_KDF_fetch(_arg0, _arg1, _arg2); +} + +void EVP_KDF_free(EVP_KDF_PTR _arg0) { + _g_EVP_KDF_free(_arg0); +} + +EVP_MAC_CTX_PTR EVP_MAC_CTX_dup(const EVP_MAC_CTX_PTR _arg0) { + return _g_EVP_MAC_CTX_dup(_arg0); +} + +void EVP_MAC_CTX_free(EVP_MAC_CTX_PTR _arg0) { + _g_EVP_MAC_CTX_free(_arg0); +} + +EVP_MAC_CTX_PTR EVP_MAC_CTX_new(EVP_MAC_PTR _arg0) { + return _g_EVP_MAC_CTX_new(_arg0); +} + +int EVP_MAC_CTX_set_params(EVP_MAC_CTX_PTR _arg0, const OSSL_PARAM_PTR _arg1) { + return _g_EVP_MAC_CTX_set_params(_arg0, _arg1); +} + +EVP_MAC_PTR EVP_MAC_fetch(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2) { + return _g_EVP_MAC_fetch(_arg0, _arg1, _arg2); +} + +int EVP_MAC_final(EVP_MAC_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2, size_t _arg3) { + return _g_EVP_MAC_final(_arg0, _arg1, _arg2, _arg3); +} + +int EVP_MAC_init(EVP_MAC_CTX_PTR _arg0, const unsigned char* _arg1, size_t _arg2, const OSSL_PARAM_PTR _arg3) { + return _g_EVP_MAC_init(_arg0, _arg1, _arg2, _arg3); +} + +int EVP_MAC_update(EVP_MAC_CTX_PTR _arg0, const unsigned char* _arg1, size_t _arg2) { + return _g_EVP_MAC_update(_arg0, _arg1, _arg2); +} + +int EVP_MD_CTX_copy(EVP_MD_CTX_PTR _arg0, const EVP_MD_CTX_PTR _arg1) { + return _g_EVP_MD_CTX_copy(_arg0, _arg1); +} + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX_PTR _arg0, const EVP_MD_CTX_PTR _arg1) { + return _g_EVP_MD_CTX_copy_ex(_arg0, _arg1); +} + +EVP_MD_CTX_PTR EVP_MD_CTX_create(void) { + return _g_EVP_MD_CTX_create(); +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX_PTR _arg0) { + _g_EVP_MD_CTX_destroy(_arg0); +} + +void EVP_MD_CTX_free(EVP_MD_CTX_PTR _arg0) { + _g_EVP_MD_CTX_free(_arg0); +} + +EVP_MD_CTX_PTR EVP_MD_CTX_new(void) { + return _g_EVP_MD_CTX_new(); +} + +int EVP_MD_block_size(const EVP_MD_PTR _arg0) { + return _g_EVP_MD_block_size(_arg0); +} + +EVP_MD_PTR EVP_MD_fetch(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2) { + return _g_EVP_MD_fetch(_arg0, _arg1, _arg2); +} + +void EVP_MD_free(EVP_MD_PTR _arg0) { + _g_EVP_MD_free(_arg0); +} + +const char* EVP_MD_get0_name(const EVP_MD_PTR _arg0) { + return _g_EVP_MD_get0_name(_arg0); +} + +const OSSL_PROVIDER_PTR EVP_MD_get0_provider(const EVP_MD_PTR _arg0) { + return _g_EVP_MD_get0_provider(_arg0); +} + +int EVP_MD_get_block_size(const EVP_MD_PTR _arg0) { + return _g_EVP_MD_get_block_size(_arg0); +} + +int EVP_MD_get_size(const EVP_MD_PTR _arg0) { + return _g_EVP_MD_get_size(_arg0); +} + +int EVP_MD_size(const EVP_MD_PTR _arg0) { + return _g_EVP_MD_size(_arg0); +} + +int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX_PTR _arg0, const unsigned char* _arg1, int _arg2) { + return _g_EVP_PKEY_CTX_add1_hkdf_info(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX_PTR _arg0, int _arg1, int _arg2, int _arg3, int _arg4, void* _arg5) { + return _g_EVP_PKEY_CTX_ctrl(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5); +} + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX_PTR _arg0) { + _g_EVP_PKEY_CTX_free(_arg0); +} + +EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new(EVP_PKEY_PTR _arg0, ENGINE_PTR _arg1) { + return _g_EVP_PKEY_CTX_new(_arg0, _arg1); +} + +EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX_PTR _arg0, EVP_PKEY_PTR _arg1, const char* _arg2) { + return _g_EVP_PKEY_CTX_new_from_pkey(_arg0, _arg1, _arg2); +} + +EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_id(int _arg0, ENGINE_PTR _arg1) { + return _g_EVP_PKEY_CTX_new_id(_arg0, _arg1); +} + +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX_PTR _arg0, void* _arg1, int _arg2) { + return _g_EVP_PKEY_CTX_set0_rsa_oaep_label(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX_PTR _arg0, const unsigned char* _arg1, int _arg2) { + return _g_EVP_PKEY_CTX_set1_hkdf_key(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX_PTR _arg0, const unsigned char* _arg1, int _arg2) { + return _g_EVP_PKEY_CTX_set1_hkdf_salt(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX_PTR _arg0, const EVP_MD_PTR _arg1) { + return _g_EVP_PKEY_CTX_set_hkdf_md(_arg0, _arg1); +} + +int EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX_PTR _arg0, int _arg1) { + return _g_EVP_PKEY_CTX_set_hkdf_mode(_arg0, _arg1); +} + +EVP_PKEY_PTR EVP_PKEY_Q_keygen_EC(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2, const char* _arg3) { + return _g_EVP_PKEY_Q_keygen_EC(_arg0, _arg1, _arg2, _arg3); +} + +EVP_PKEY_PTR EVP_PKEY_Q_keygen_ED25519(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2) { + return _g_EVP_PKEY_Q_keygen_ED25519(_arg0, _arg1, _arg2); +} + +EVP_PKEY_PTR EVP_PKEY_Q_keygen_RSA(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2, size_t _arg3) { + return _g_EVP_PKEY_Q_keygen_RSA(_arg0, _arg1, _arg2, _arg3); +} + +int EVP_PKEY_assign(EVP_PKEY_PTR _arg0, int _arg1, void* _arg2) { + return _g_EVP_PKEY_assign(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_bits(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_bits(_arg0); +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2, const unsigned char* _arg3, size_t _arg4) { + return _g_EVP_PKEY_decrypt(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_decrypt_init(_arg0); +} + +int EVP_PKEY_derive(EVP_PKEY_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2) { + return _g_EVP_PKEY_derive(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_derive_init(_arg0); +} + +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX_PTR _arg0, EVP_PKEY_PTR _arg1) { + return _g_EVP_PKEY_derive_set_peer(_arg0, _arg1); +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2, const unsigned char* _arg3, size_t _arg4) { + return _g_EVP_PKEY_encrypt(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_encrypt_init(_arg0); +} + +void EVP_PKEY_free(EVP_PKEY_PTR _arg0) { + _g_EVP_PKEY_free(_arg0); +} + +int EVP_PKEY_fromdata(EVP_PKEY_CTX_PTR _arg0, EVP_PKEY_PTR* _arg1, int _arg2, OSSL_PARAM_PTR _arg3) { + return _g_EVP_PKEY_fromdata(_arg0, _arg1, _arg2, _arg3); +} + +int EVP_PKEY_fromdata_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_fromdata_init(_arg0); +} + +void* EVP_PKEY_get0(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_get0(_arg0); +} + +const DSA_PTR EVP_PKEY_get0_DSA(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_get0_DSA(_arg0); +} + +const EC_KEY_PTR EVP_PKEY_get0_EC_KEY(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_get0_EC_KEY(_arg0); +} + +RSA_PTR EVP_PKEY_get1_RSA(EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_get1_RSA(_arg0); +} + +size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY_PTR _arg0, unsigned char** _arg1) { + return _g_EVP_PKEY_get1_encoded_public_key(_arg0, _arg1); +} + +int EVP_PKEY_get_bits(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_get_bits(_arg0); +} + +int EVP_PKEY_get_bn_param(const EVP_PKEY_PTR _arg0, const char* _arg1, BIGNUM_PTR* _arg2) { + return _g_EVP_PKEY_get_bn_param(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_get_raw_private_key(const EVP_PKEY_PTR _arg0, unsigned char* _arg1, size_t* _arg2) { + return _g_EVP_PKEY_get_raw_private_key(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_get_raw_public_key(const EVP_PKEY_PTR _arg0, unsigned char* _arg1, size_t* _arg2) { + return _g_EVP_PKEY_get_raw_public_key(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_get_size(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_get_size(_arg0); +} + +int EVP_PKEY_keygen(EVP_PKEY_CTX_PTR _arg0, EVP_PKEY_PTR* _arg1) { + return _g_EVP_PKEY_keygen(_arg0, _arg1); +} + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_keygen_init(_arg0); +} + +EVP_PKEY_PTR EVP_PKEY_new(void) { + return _g_EVP_PKEY_new(); +} + +EVP_PKEY_PTR EVP_PKEY_new_raw_private_key(int _arg0, ENGINE_PTR _arg1, const unsigned char* _arg2, size_t _arg3) { + return _g_EVP_PKEY_new_raw_private_key(_arg0, _arg1, _arg2, _arg3); +} + +EVP_PKEY_PTR EVP_PKEY_new_raw_public_key(int _arg0, ENGINE_PTR _arg1, const unsigned char* _arg2, size_t _arg3) { + return _g_EVP_PKEY_new_raw_public_key(_arg0, _arg1, _arg2, _arg3); +} + +int EVP_PKEY_paramgen(EVP_PKEY_CTX_PTR _arg0, EVP_PKEY_PTR* _arg1) { + return _g_EVP_PKEY_paramgen(_arg0, _arg1); +} + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_paramgen_init(_arg0); +} + +int EVP_PKEY_set1_EC_KEY(EVP_PKEY_PTR _arg0, EC_KEY_PTR _arg1) { + return _g_EVP_PKEY_set1_EC_KEY(_arg0, _arg1); +} + +int EVP_PKEY_set1_encoded_public_key(EVP_PKEY_PTR _arg0, const unsigned char* _arg1, size_t _arg2) { + return _g_EVP_PKEY_set1_encoded_public_key(_arg0, _arg1, _arg2); +} + +int EVP_PKEY_sign(EVP_PKEY_CTX_PTR _arg0, unsigned char* _arg1, size_t* _arg2, const unsigned char* _arg3, size_t _arg4) { + return _g_EVP_PKEY_sign(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_PKEY_sign_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_sign_init(_arg0); +} + +int EVP_PKEY_size(const EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_size(_arg0); +} + +int EVP_PKEY_up_ref(EVP_PKEY_PTR _arg0) { + return _g_EVP_PKEY_up_ref(_arg0); +} + +int EVP_PKEY_verify(EVP_PKEY_CTX_PTR _arg0, const unsigned char* _arg1, size_t _arg2, const unsigned char* _arg3, size_t _arg4) { + return _g_EVP_PKEY_verify(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX_PTR _arg0) { + return _g_EVP_PKEY_verify_init(_arg0); +} + +EVP_SIGNATURE_PTR EVP_SIGNATURE_fetch(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, const char* _arg2) { + return _g_EVP_SIGNATURE_fetch(_arg0, _arg1, _arg2); +} + +void EVP_SIGNATURE_free(EVP_SIGNATURE_PTR _arg0) { + _g_EVP_SIGNATURE_free(_arg0); +} + +EVP_CIPHER_PTR EVP_aes_128_cbc(void) { + return _g_EVP_aes_128_cbc(); +} + +EVP_CIPHER_PTR EVP_aes_128_ctr(void) { + return _g_EVP_aes_128_ctr(); +} + +EVP_CIPHER_PTR EVP_aes_128_ecb(void) { + return _g_EVP_aes_128_ecb(); +} + +EVP_CIPHER_PTR EVP_aes_128_gcm(void) { + return _g_EVP_aes_128_gcm(); +} + +EVP_CIPHER_PTR EVP_aes_192_cbc(void) { + return _g_EVP_aes_192_cbc(); +} + +EVP_CIPHER_PTR EVP_aes_192_ctr(void) { + return _g_EVP_aes_192_ctr(); +} + +EVP_CIPHER_PTR EVP_aes_192_ecb(void) { + return _g_EVP_aes_192_ecb(); +} + +EVP_CIPHER_PTR EVP_aes_192_gcm(void) { + return _g_EVP_aes_192_gcm(); +} + +EVP_CIPHER_PTR EVP_aes_256_cbc(void) { + return _g_EVP_aes_256_cbc(); +} + +EVP_CIPHER_PTR EVP_aes_256_ctr(void) { + return _g_EVP_aes_256_ctr(); +} + +EVP_CIPHER_PTR EVP_aes_256_ecb(void) { + return _g_EVP_aes_256_ecb(); +} + +EVP_CIPHER_PTR EVP_aes_256_gcm(void) { + return _g_EVP_aes_256_gcm(); +} + +int EVP_default_properties_enable_fips(OSSL_LIB_CTX_PTR _arg0, int _arg1) { + return _g_EVP_default_properties_enable_fips(_arg0, _arg1); +} + +int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX_PTR _arg0) { + return _g_EVP_default_properties_is_fips_enabled(_arg0); +} + +EVP_CIPHER_PTR EVP_des_cbc(void) { + return _g_EVP_des_cbc(); +} + +EVP_CIPHER_PTR EVP_des_ecb(void) { + return _g_EVP_des_ecb(); +} + +EVP_CIPHER_PTR EVP_des_ede3_cbc(void) { + return _g_EVP_des_ede3_cbc(); +} + +EVP_CIPHER_PTR EVP_des_ede3_ecb(void) { + return _g_EVP_des_ede3_ecb(); +} + +const EVP_MD_PTR EVP_md4(void) { + return _g_EVP_md4(); +} + +const EVP_MD_PTR EVP_md5(void) { + return _g_EVP_md5(); +} + +const EVP_MD_PTR EVP_md5_sha1(void) { + return _g_EVP_md5_sha1(); +} + +EVP_CIPHER_PTR EVP_rc4(void) { + return _g_EVP_rc4(); +} + +const EVP_MD_PTR EVP_sha1(void) { + return _g_EVP_sha1(); +} + +const EVP_MD_PTR EVP_sha224(void) { + return _g_EVP_sha224(); +} + +const EVP_MD_PTR EVP_sha256(void) { + return _g_EVP_sha256(); +} + +const EVP_MD_PTR EVP_sha384(void) { + return _g_EVP_sha384(); +} + +const EVP_MD_PTR EVP_sha3_224(void) { + return _g_EVP_sha3_224(); +} + +const EVP_MD_PTR EVP_sha3_256(void) { + return _g_EVP_sha3_256(); +} + +const EVP_MD_PTR EVP_sha3_384(void) { + return _g_EVP_sha3_384(); +} + +const EVP_MD_PTR EVP_sha3_512(void) { + return _g_EVP_sha3_512(); +} + +const EVP_MD_PTR EVP_sha512(void) { + return _g_EVP_sha512(); +} + +int FIPS_mode(void) { + return _g_FIPS_mode(); +} + +int FIPS_mode_set(int _arg0) { + return _g_FIPS_mode_set(_arg0); +} + +void HMAC_CTX_cleanup(HMAC_CTX_PTR _arg0) { + _g_HMAC_CTX_cleanup(_arg0); +} + +int HMAC_CTX_copy(HMAC_CTX_PTR _arg0, HMAC_CTX_PTR _arg1) { + return _g_HMAC_CTX_copy(_arg0, _arg1); +} + +void HMAC_CTX_free(HMAC_CTX_PTR _arg0) { + _g_HMAC_CTX_free(_arg0); +} + +void HMAC_CTX_init(HMAC_CTX_PTR _arg0) { + _g_HMAC_CTX_init(_arg0); +} + +HMAC_CTX_PTR HMAC_CTX_new(void) { + return _g_HMAC_CTX_new(); +} + +int HMAC_Final(HMAC_CTX_PTR _arg0, unsigned char* _arg1, unsigned int* _arg2) { + return _g_HMAC_Final(_arg0, _arg1, _arg2); +} + +int HMAC_Init_ex(HMAC_CTX_PTR _arg0, const void* _arg1, int _arg2, const EVP_MD_PTR _arg3, ENGINE_PTR _arg4) { + return _g_HMAC_Init_ex(_arg0, _arg1, _arg2, _arg3, _arg4); +} + +int HMAC_Update(HMAC_CTX_PTR _arg0, const unsigned char* _arg1, size_t _arg2) { + return _g_HMAC_Update(_arg0, _arg1, _arg2); +} + +int MD5_Final(unsigned char* _arg0, MD5_CTX_PTR _arg1) { + return _g_MD5_Final(_arg0, _arg1); +} + +int MD5_Init(MD5_CTX_PTR _arg0) { + return _g_MD5_Init(_arg0); +} + +int MD5_Update(MD5_CTX_PTR _arg0, const void* _arg1, size_t _arg2) { + return _g_MD5_Update(_arg0, _arg1, _arg2); +} + +const char* OBJ_nid2sn(int _arg0) { + return _g_OBJ_nid2sn(_arg0); +} + +void OPENSSL_add_all_algorithms_conf(void) { + _g_OPENSSL_add_all_algorithms_conf(); +} + +void OPENSSL_init(void) { + _g_OPENSSL_init(); +} + +int OPENSSL_init_crypto(uint64_t _arg0, const OPENSSL_INIT_SETTINGS_PTR _arg1) { + return _g_OPENSSL_init_crypto(_arg0, _arg1); +} + +void OSSL_PARAM_BLD_free(OSSL_PARAM_BLD_PTR _arg0) { + _g_OSSL_PARAM_BLD_free(_arg0); +} + +OSSL_PARAM_BLD_PTR OSSL_PARAM_BLD_new(void) { + return _g_OSSL_PARAM_BLD_new(); +} + +int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD_PTR _arg0, const char* _arg1, const BIGNUM_PTR _arg2) { + return _g_OSSL_PARAM_BLD_push_BN(_arg0, _arg1, _arg2); +} + +int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD_PTR _arg0, const char* _arg1, int32_t _arg2) { + return _g_OSSL_PARAM_BLD_push_int32(_arg0, _arg1, _arg2); +} + +int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD_PTR _arg0, const char* _arg1, const void* _arg2, size_t _arg3) { + return _g_OSSL_PARAM_BLD_push_octet_string(_arg0, _arg1, _arg2, _arg3); +} + +int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD_PTR _arg0, const char* _arg1, const char* _arg2, size_t _arg3) { + return _g_OSSL_PARAM_BLD_push_utf8_string(_arg0, _arg1, _arg2, _arg3); +} + +OSSL_PARAM_PTR OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD_PTR _arg0) { + return _g_OSSL_PARAM_BLD_to_param(_arg0); +} + +void OSSL_PARAM_free(OSSL_PARAM_PTR _arg0) { + _g_OSSL_PARAM_free(_arg0); +} + +int OSSL_PROVIDER_available(OSSL_LIB_CTX_PTR _arg0, const char* _arg1) { + return _g_OSSL_PROVIDER_available(_arg0, _arg1); +} + +const char* OSSL_PROVIDER_get0_name(const OSSL_PROVIDER_PTR _arg0) { + return _g_OSSL_PROVIDER_get0_name(_arg0); +} + +OSSL_PROVIDER_PTR OSSL_PROVIDER_try_load(OSSL_LIB_CTX_PTR _arg0, const char* _arg1, int _arg2) { + return _g_OSSL_PROVIDER_try_load(_arg0, _arg1, _arg2); +} + +const char* OpenSSL_version(int _arg0) { + return _g_OpenSSL_version(_arg0); +} + +int PKCS5_PBKDF2_HMAC(const char* _arg0, int _arg1, const unsigned char* _arg2, int _arg3, int _arg4, const EVP_MD_PTR _arg5, int _arg6, unsigned char* _arg7) { + return _g_PKCS5_PBKDF2_HMAC(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7); +} + +int RAND_bytes(unsigned char* _arg0, int _arg1) { + return _g_RAND_bytes(_arg0, _arg1); +} + +void RSA_free(RSA_PTR _arg0) { + _g_RSA_free(_arg0); +} + +void RSA_get0_crt_params(const RSA_PTR _arg0, const BIGNUM_PTR* _arg1, const BIGNUM_PTR* _arg2, const BIGNUM_PTR* _arg3) { + _g_RSA_get0_crt_params(_arg0, _arg1, _arg2, _arg3); +} + +void RSA_get0_factors(const RSA_PTR _arg0, const BIGNUM_PTR* _arg1, const BIGNUM_PTR* _arg2) { + _g_RSA_get0_factors(_arg0, _arg1, _arg2); +} + +void RSA_get0_key(const RSA_PTR _arg0, const BIGNUM_PTR* _arg1, const BIGNUM_PTR* _arg2, const BIGNUM_PTR* _arg3) { + _g_RSA_get0_key(_arg0, _arg1, _arg2, _arg3); +} + +RSA_PTR RSA_new(void) { + return _g_RSA_new(); +} + +int RSA_set0_crt_params(RSA_PTR _arg0, BIGNUM_PTR _arg1, BIGNUM_PTR _arg2, BIGNUM_PTR _arg3) { + return _g_RSA_set0_crt_params(_arg0, _arg1, _arg2, _arg3); +} + +int RSA_set0_factors(RSA_PTR _arg0, BIGNUM_PTR _arg1, BIGNUM_PTR _arg2) { + return _g_RSA_set0_factors(_arg0, _arg1, _arg2); +} + +int RSA_set0_key(RSA_PTR _arg0, BIGNUM_PTR _arg1, BIGNUM_PTR _arg2, BIGNUM_PTR _arg3) { + return _g_RSA_set0_key(_arg0, _arg1, _arg2, _arg3); +} + +int SHA1_Final(unsigned char* _arg0, SHA_CTX_PTR _arg1) { + return _g_SHA1_Final(_arg0, _arg1); +} + +int SHA1_Init(SHA_CTX_PTR _arg0) { + return _g_SHA1_Init(_arg0); +} + +int SHA1_Update(SHA_CTX_PTR _arg0, const void* _arg1, size_t _arg2) { + return _g_SHA1_Update(_arg0, _arg1, _arg2); +} + +const char* SSLeay_version(int _arg0) { + return _g_SSLeay_version(_arg0); +} + +BIGNUM_PTR bn_expand2(BIGNUM_PTR _arg0, int _arg1) { + return _g_bn_expand2(_arg0, _arg1); +} + diff --git a/internal/ossl/zossl.go b/internal/ossl/zossl.go new file mode 100644 index 00000000..c415dc89 --- /dev/null +++ b/internal/ossl/zossl.go @@ -0,0 +1,1629 @@ +// Code generated by mkcgo. DO NOT EDIT. + +package ossl + +/* +#include "ossl.h" +#include "api.h" +void __mkcgoLoad_crypto(void* handle); +*/ +import "C" +import ( + "unsafe" +) + +func mkcgoLoad_crypto(handle unsafe.Pointer) { + C.__mkcgoLoad_crypto(handle) +} + +func BN_bin2bn(arg0 *byte, arg1 int32, arg2 BIGNUM_PTR) (_r0 BIGNUM_PTR, err error) { + r0 := C.BN_bin2bn((*C.uchar)(unsafe.Pointer(arg0)), C.int(arg1), C.BIGNUM_PTR(arg2)) + _r0 = BIGNUM_PTR(r0) + if _r0 == nil { + err = newError("BN_bin2bn") + } + return +} + +func BN_bn2bin(a BIGNUM_PTR, to *byte) (_r0 int32) { + r0 := C.BN_bn2bin(C.BIGNUM_PTR(a), (*C.uchar)(unsafe.Pointer(to))) + _r0 = int32(r0) + return +} + +func BN_bn2binpad(a BIGNUM_PTR, to *byte, tolen int32) (_r0 int32, err error) { + r0 := C.BN_bn2binpad(C.BIGNUM_PTR(a), (*C.uchar)(unsafe.Pointer(to)), C.int(tolen)) + _r0 = int32(r0) + if _r0 == -1 { + err = newError("BN_bn2binpad") + } + return +} + +func BN_bn2lebinpad(a BIGNUM_PTR, to *byte, tolen int32) (_r0 int32, err error) { + r0 := C.BN_bn2lebinpad(C.BIGNUM_PTR(a), (*C.uchar)(unsafe.Pointer(to)), C.int(tolen)) + _r0 = int32(r0) + if _r0 == -1 { + err = newError("BN_bn2lebinpad") + } + return +} + +func BN_clear(arg0 BIGNUM_PTR) { + C.BN_clear(C.BIGNUM_PTR(arg0)) +} + +func BN_clear_free(arg0 BIGNUM_PTR) { + C.BN_clear_free(C.BIGNUM_PTR(arg0)) +} + +func BN_free(arg0 BIGNUM_PTR) { + C.BN_free(C.BIGNUM_PTR(arg0)) +} + +func BN_lebin2bn(s *byte, len int32, ret BIGNUM_PTR) (_r0 BIGNUM_PTR, err error) { + r0 := C.BN_lebin2bn((*C.uchar)(unsafe.Pointer(s)), C.int(len), C.BIGNUM_PTR(ret)) + _r0 = BIGNUM_PTR(r0) + if _r0 == nil { + err = newError("BN_lebin2bn") + } + return +} + +func BN_new() (_r0 BIGNUM_PTR, err error) { + r0 := C.BN_new() + _r0 = BIGNUM_PTR(r0) + if _r0 == nil { + err = newError("BN_new") + } + return +} + +func BN_num_bits(arg0 BIGNUM_PTR) (_r0 int32) { + r0 := C.BN_num_bits(C.BIGNUM_PTR(arg0)) + _r0 = int32(r0) + return +} + +func CRYPTO_free(str unsafe.Pointer, file *byte, line int32) { + C.CRYPTO_free(str, (*C.char)(unsafe.Pointer(file)), C.int(line)) +} + +func CRYPTO_malloc(num int, file *byte, line int32) (_r0 unsafe.Pointer) { + r0 := C.CRYPTO_malloc(C.size_t(num), (*C.char)(unsafe.Pointer(file)), C.int(line)) + _r0 = unsafe.Pointer(r0) + return +} + +func DSA_free(r DSA_PTR) { + C.DSA_free(C.DSA_PTR(r)) +} + +func DSA_generate_key(a DSA_PTR) (err error) { + r0 := C.DSA_generate_key(C.DSA_PTR(a)) + if r0 != 1 { + err = newError("DSA_generate_key") + } + return +} + +func DSA_get0_key(d DSA_PTR, pub_key *BIGNUM_PTR, priv_key *BIGNUM_PTR) { + C.DSA_get0_key(C.DSA_PTR(d), (*C.BIGNUM_PTR)(unsafe.Pointer(pub_key)), (*C.BIGNUM_PTR)(unsafe.Pointer(priv_key))) +} + +func DSA_get0_pqg(d DSA_PTR, p *BIGNUM_PTR, q *BIGNUM_PTR, g *BIGNUM_PTR) { + C.DSA_get0_pqg(C.DSA_PTR(d), (*C.BIGNUM_PTR)(unsafe.Pointer(p)), (*C.BIGNUM_PTR)(unsafe.Pointer(q)), (*C.BIGNUM_PTR)(unsafe.Pointer(g))) +} + +func DSA_new() (_r0 DSA_PTR, err error) { + r0 := C.DSA_new() + _r0 = DSA_PTR(r0) + if _r0 == nil { + err = newError("DSA_new") + } + return +} + +func DSA_set0_key(d DSA_PTR, pub_key BIGNUM_PTR, priv_key BIGNUM_PTR) (err error) { + r0 := C.DSA_set0_key(C.DSA_PTR(d), C.BIGNUM_PTR(pub_key), C.BIGNUM_PTR(priv_key)) + if r0 != 1 { + err = newError("DSA_set0_key") + } + return +} + +func DSA_set0_pqg(d DSA_PTR, p BIGNUM_PTR, q BIGNUM_PTR, g BIGNUM_PTR) (err error) { + r0 := C.DSA_set0_pqg(C.DSA_PTR(d), C.BIGNUM_PTR(p), C.BIGNUM_PTR(q), C.BIGNUM_PTR(g)) + if r0 != 1 { + err = newError("DSA_set0_pqg") + } + return +} + +func EC_GROUP_free(group EC_GROUP_PTR) { + C.EC_GROUP_free(C.EC_GROUP_PTR(group)) +} + +func EC_GROUP_new_by_curve_name(nid int32) (_r0 EC_GROUP_PTR, err error) { + r0 := C.EC_GROUP_new_by_curve_name(C.int(nid)) + _r0 = EC_GROUP_PTR(r0) + if _r0 == nil { + err = newError("EC_GROUP_new_by_curve_name") + } + return +} + +func EC_KEY_free(arg0 EC_KEY_PTR) { + C.EC_KEY_free(C.EC_KEY_PTR(arg0)) +} + +func EC_KEY_get0_group(arg0 EC_KEY_PTR) (_r0 EC_GROUP_PTR, err error) { + r0 := C.EC_KEY_get0_group(C.EC_KEY_PTR(arg0)) + _r0 = EC_GROUP_PTR(r0) + if _r0 == nil { + err = newError("EC_KEY_get0_group") + } + return +} + +func EC_KEY_get0_private_key(arg0 EC_KEY_PTR) (_r0 BIGNUM_PTR, err error) { + r0 := C.EC_KEY_get0_private_key(C.EC_KEY_PTR(arg0)) + _r0 = BIGNUM_PTR(r0) + if _r0 == nil { + err = newError("EC_KEY_get0_private_key") + } + return +} + +func EC_KEY_get0_public_key(arg0 EC_KEY_PTR) (_r0 EC_POINT_PTR, err error) { + r0 := C.EC_KEY_get0_public_key(C.EC_KEY_PTR(arg0)) + _r0 = EC_POINT_PTR(r0) + if _r0 == nil { + err = newError("EC_KEY_get0_public_key") + } + return +} + +func EC_KEY_new_by_curve_name(arg0 int32) (_r0 EC_KEY_PTR, err error) { + r0 := C.EC_KEY_new_by_curve_name(C.int(arg0)) + _r0 = EC_KEY_PTR(r0) + if _r0 == nil { + err = newError("EC_KEY_new_by_curve_name") + } + return +} + +func EC_KEY_set_private_key(arg0 EC_KEY_PTR, arg1 BIGNUM_PTR) (err error) { + r0 := C.EC_KEY_set_private_key(C.EC_KEY_PTR(arg0), C.BIGNUM_PTR(arg1)) + if r0 != 1 { + err = newError("EC_KEY_set_private_key") + } + return +} + +func EC_KEY_set_public_key(key EC_KEY_PTR, pub EC_POINT_PTR) (err error) { + r0 := C.EC_KEY_set_public_key(C.EC_KEY_PTR(key), C.EC_POINT_PTR(pub)) + if r0 != 1 { + err = newError("EC_KEY_set_public_key") + } + return +} + +func EC_KEY_set_public_key_affine_coordinates(key EC_KEY_PTR, x BIGNUM_PTR, y BIGNUM_PTR) (err error) { + r0 := C.EC_KEY_set_public_key_affine_coordinates(C.EC_KEY_PTR(key), C.BIGNUM_PTR(x), C.BIGNUM_PTR(y)) + if r0 != 1 { + err = newError("EC_KEY_set_public_key_affine_coordinates") + } + return +} + +func EC_POINT_free(arg0 EC_POINT_PTR) { + C.EC_POINT_free(C.EC_POINT_PTR(arg0)) +} + +func EC_POINT_get_affine_coordinates_GFp(arg0 EC_GROUP_PTR, arg1 EC_POINT_PTR, arg2 BIGNUM_PTR, arg3 BIGNUM_PTR, arg4 BN_CTX_PTR) (err error) { + r0 := C.EC_POINT_get_affine_coordinates_GFp(C.EC_GROUP_PTR(arg0), C.EC_POINT_PTR(arg1), C.BIGNUM_PTR(arg2), C.BIGNUM_PTR(arg3), C.BN_CTX_PTR(arg4)) + if r0 != 1 { + err = newError("EC_POINT_get_affine_coordinates_GFp") + } + return +} + +func EC_POINT_mul(group EC_GROUP_PTR, r EC_POINT_PTR, n BIGNUM_PTR, q EC_POINT_PTR, m BIGNUM_PTR, ctx BN_CTX_PTR) (err error) { + r0 := C.EC_POINT_mul(C.EC_GROUP_PTR(group), C.EC_POINT_PTR(r), C.BIGNUM_PTR(n), C.EC_POINT_PTR(q), C.BIGNUM_PTR(m), C.BN_CTX_PTR(ctx)) + if r0 != 1 { + err = newError("EC_POINT_mul") + } + return +} + +func EC_POINT_new(arg0 EC_GROUP_PTR) (_r0 EC_POINT_PTR, err error) { + r0 := C.EC_POINT_new(C.EC_GROUP_PTR(arg0)) + _r0 = EC_POINT_PTR(r0) + if _r0 == nil { + err = newError("EC_POINT_new") + } + return +} + +func EC_POINT_oct2point(group EC_GROUP_PTR, p EC_POINT_PTR, buf *byte, len int, ctx BN_CTX_PTR) (err error) { + r0 := C.EC_POINT_oct2point(C.EC_GROUP_PTR(group), C.EC_POINT_PTR(p), (*C.uchar)(unsafe.Pointer(buf)), C.size_t(len), C.BN_CTX_PTR(ctx)) + if r0 != 1 { + err = newError("EC_POINT_oct2point") + } + return +} + +func EC_POINT_point2oct(group EC_GROUP_PTR, p EC_POINT_PTR, form Point_conversion_form_t, buf *byte, len int, ctx BN_CTX_PTR) (_r0 int, err error) { + r0 := C.EC_POINT_point2oct(C.EC_GROUP_PTR(group), C.EC_POINT_PTR(p), C.point_conversion_form_t(form), (*C.uchar)(unsafe.Pointer(buf)), C.size_t(len), C.BN_CTX_PTR(ctx)) + _r0 = int(r0) + if _r0 == 0 { + err = newError("EC_POINT_point2oct") + } + return +} + +func EC_POINT_set_affine_coordinates(arg0 EC_GROUP_PTR, arg1 EC_POINT_PTR, arg2 BIGNUM_PTR, arg3 BIGNUM_PTR, arg4 BN_CTX_PTR) (err error) { + r0 := C.EC_POINT_set_affine_coordinates(C.EC_GROUP_PTR(arg0), C.EC_POINT_PTR(arg1), C.BIGNUM_PTR(arg2), C.BIGNUM_PTR(arg3), C.BN_CTX_PTR(arg4)) + if r0 != 1 { + err = newError("EC_POINT_set_affine_coordinates") + } + return +} + +func ERR_clear_error() { + C.ERR_clear_error() +} + +func ERR_error_string_n(e uint64, buf *byte, len int) { + C.ERR_error_string_n(C.ulong(e), (*C.char)(unsafe.Pointer(buf)), C.size_t(len)) +} + +func ERR_get_error_all(file **byte, line *int32, fn **byte, data **byte, flags *int32) (_r0 uint64) { + r0 := C.ERR_get_error_all((**C.char)(unsafe.Pointer(file)), (*C.int)(unsafe.Pointer(line)), (**C.char)(unsafe.Pointer(fn)), (**C.char)(unsafe.Pointer(data)), (*C.int)(unsafe.Pointer(flags))) + _r0 = uint64(r0) + return +} + +func ERR_get_error_line(file **byte, line *int32) (_r0 uint64) { + r0 := C.ERR_get_error_line((**C.char)(unsafe.Pointer(file)), (*C.int)(unsafe.Pointer(line))) + _r0 = uint64(r0) + return +} + +func ERR_load_crypto_strings() { + C.ERR_load_crypto_strings() +} + +func EVP_CIPHER_CTX_ctrl(ctx EVP_CIPHER_CTX_PTR, cmd int32, p1 int32, p2 unsafe.Pointer) (err error) { + r0 := C.EVP_CIPHER_CTX_ctrl(C.EVP_CIPHER_CTX_PTR(ctx), C.int(cmd), C.int(p1), p2) + if r0 != 1 { + err = newError("EVP_CIPHER_CTX_ctrl") + } + return +} + +func EVP_CIPHER_CTX_free(ctx EVP_CIPHER_CTX_PTR) { + C.EVP_CIPHER_CTX_free(C.EVP_CIPHER_CTX_PTR(ctx)) +} + +func EVP_CIPHER_CTX_new() (_r0 EVP_CIPHER_CTX_PTR, err error) { + r0 := C.EVP_CIPHER_CTX_new() + _r0 = EVP_CIPHER_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_CIPHER_CTX_new") + } + return +} + +func EVP_CIPHER_CTX_set_key_length(ctx EVP_CIPHER_CTX_PTR, keylen int32) (err error) { + r0 := C.EVP_CIPHER_CTX_set_key_length(C.EVP_CIPHER_CTX_PTR(ctx), C.int(keylen)) + if r0 != 1 { + err = newError("EVP_CIPHER_CTX_set_key_length") + } + return +} + +func EVP_CIPHER_CTX_set_padding(x EVP_CIPHER_CTX_PTR, padding int32) (err error) { + r0 := C.EVP_CIPHER_CTX_set_padding(C.EVP_CIPHER_CTX_PTR(x), C.int(padding)) + if r0 != 1 { + err = newError("EVP_CIPHER_CTX_set_padding") + } + return +} + +func _EVP_CIPHER_block_size(e EVP_CIPHER_PTR) (_r0 int32) { + r0 := C.EVP_CIPHER_block_size(C.EVP_CIPHER_PTR(e)) + _r0 = int32(r0) + return +} + +func EVP_CIPHER_fetch(ctx OSSL_LIB_CTX_PTR, algorithm *byte, properties *byte) (_r0 EVP_CIPHER_PTR, err error) { + r0 := C.EVP_CIPHER_fetch(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(algorithm)), (*C.char)(unsafe.Pointer(properties))) + _r0 = EVP_CIPHER_PTR(r0) + if _r0 == nil { + err = newError("EVP_CIPHER_fetch") + } + return +} + +func EVP_CIPHER_get0_name(cipher EVP_CIPHER_PTR) (_r0 *byte) { + r0 := C.EVP_CIPHER_get0_name(C.EVP_CIPHER_PTR(cipher)) + _r0 = (*byte)(unsafe.Pointer(r0)) + return +} + +func _EVP_CIPHER_get_block_size(e EVP_CIPHER_PTR) (_r0 int32) { + r0 := C.EVP_CIPHER_get_block_size(C.EVP_CIPHER_PTR(e)) + _r0 = int32(r0) + return +} + +func EVP_CipherInit_ex(ctx EVP_CIPHER_CTX_PTR, typ EVP_CIPHER_PTR, impl ENGINE_PTR, key *byte, iv *byte, enc int32) (err error) { + r0 := C.EVP_CipherInit_ex(C.EVP_CIPHER_CTX_PTR(ctx), C.EVP_CIPHER_PTR(typ), C.ENGINE_PTR(impl), (*C.uchar)(unsafe.Pointer(key)), (*C.uchar)(unsafe.Pointer(iv)), C.int(enc)) + if r0 != 1 { + err = newError("EVP_CipherInit_ex") + } + return +} + +func EVP_CipherUpdate(ctx EVP_CIPHER_CTX_PTR, out *byte, outl *int32, in *byte, inl int32) (err error) { + r0 := C.EVP_CipherUpdate(C.EVP_CIPHER_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(out)), (*C.int)(unsafe.Pointer(outl)), (*C.uchar)(unsafe.Pointer(in)), C.int(inl)) + if r0 != 1 { + err = newError("EVP_CipherUpdate") + } + return +} + +func EVP_DecryptFinal_ex(ctx EVP_CIPHER_CTX_PTR, outm *byte, outl *int32) (err error) { + r0 := C.EVP_DecryptFinal_ex(C.EVP_CIPHER_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(outm)), (*C.int)(unsafe.Pointer(outl))) + if r0 != 1 { + err = newError("EVP_DecryptFinal_ex") + } + return +} + +func EVP_DecryptInit_ex(ctx EVP_CIPHER_CTX_PTR, typ EVP_CIPHER_PTR, impl ENGINE_PTR, key *byte, iv *byte) (err error) { + r0 := C.EVP_DecryptInit_ex(C.EVP_CIPHER_CTX_PTR(ctx), C.EVP_CIPHER_PTR(typ), C.ENGINE_PTR(impl), (*C.uchar)(unsafe.Pointer(key)), (*C.uchar)(unsafe.Pointer(iv))) + if r0 != 1 { + err = newError("EVP_DecryptInit_ex") + } + return +} + +func EVP_DecryptUpdate(ctx EVP_CIPHER_CTX_PTR, out *byte, outl *int32, in *byte, inl int32) (err error) { + r0 := C.EVP_DecryptUpdate(C.EVP_CIPHER_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(out)), (*C.int)(unsafe.Pointer(outl)), (*C.uchar)(unsafe.Pointer(in)), C.int(inl)) + if r0 != 1 { + err = newError("EVP_DecryptUpdate") + } + return +} + +func EVP_Digest(data unsafe.Pointer, count int, md *byte, size *uint32, typ EVP_MD_PTR, impl ENGINE_PTR) (err error) { + r0 := C.EVP_Digest(data, C.size_t(count), (*C.uchar)(unsafe.Pointer(md)), (*C.uint)(unsafe.Pointer(size)), C.EVP_MD_PTR(typ), C.ENGINE_PTR(impl)) + if r0 != 1 { + err = newError("EVP_Digest") + } + return +} + +func EVP_DigestFinal(ctx EVP_MD_CTX_PTR, md *byte, s *uint32) (err error) { + r0 := C.EVP_DigestFinal(C.EVP_MD_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(md)), (*C.uint)(unsafe.Pointer(s))) + if r0 != 1 { + err = newError("EVP_DigestFinal") + } + return +} + +func EVP_DigestInit(ctx EVP_MD_CTX_PTR, typ EVP_MD_PTR) (err error) { + r0 := C.EVP_DigestInit(C.EVP_MD_CTX_PTR(ctx), C.EVP_MD_PTR(typ)) + if r0 != 1 { + err = newError("EVP_DigestInit") + } + return +} + +func EVP_DigestInit_ex(ctx EVP_MD_CTX_PTR, typ EVP_MD_PTR, impl ENGINE_PTR) (err error) { + r0 := C.EVP_DigestInit_ex(C.EVP_MD_CTX_PTR(ctx), C.EVP_MD_PTR(typ), C.ENGINE_PTR(impl)) + if r0 != 1 { + err = newError("EVP_DigestInit_ex") + } + return +} + +func EVP_DigestSign(ctx EVP_MD_CTX_PTR, sigret *byte, siglen *int, tbs *byte, tbslen int) (err error) { + r0 := C.EVP_DigestSign(C.EVP_MD_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(sigret)), (*C.size_t)(unsafe.Pointer(siglen)), (*C.uchar)(unsafe.Pointer(tbs)), C.size_t(tbslen)) + if r0 != 1 { + err = newError("EVP_DigestSign") + } + return +} + +func EVP_DigestSignFinal(ctx EVP_MD_CTX_PTR, sig *byte, siglen *int) (err error) { + r0 := C.EVP_DigestSignFinal(C.EVP_MD_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(sig)), (*C.size_t)(unsafe.Pointer(siglen))) + if r0 != 1 { + err = newError("EVP_DigestSignFinal") + } + return +} + +func EVP_DigestSignInit(ctx EVP_MD_CTX_PTR, pctx *EVP_PKEY_CTX_PTR, typ EVP_MD_PTR, e ENGINE_PTR, pkey EVP_PKEY_PTR) (err error) { + r0 := C.EVP_DigestSignInit(C.EVP_MD_CTX_PTR(ctx), (*C.EVP_PKEY_CTX_PTR)(unsafe.Pointer(pctx)), C.EVP_MD_PTR(typ), C.ENGINE_PTR(e), C.EVP_PKEY_PTR(pkey)) + if r0 != 1 { + err = newError("EVP_DigestSignInit") + } + return +} + +func EVP_DigestUpdate(ctx EVP_MD_CTX_PTR, d unsafe.Pointer, cnt int) (err error) { + r0 := C.EVP_DigestUpdate(C.EVP_MD_CTX_PTR(ctx), d, C.size_t(cnt)) + if r0 != 1 { + err = newError("EVP_DigestUpdate") + } + return +} + +func EVP_DigestVerify(ctx EVP_MD_CTX_PTR, sigret *byte, siglen int, tbs *byte, tbslen int) (err error) { + r0 := C.EVP_DigestVerify(C.EVP_MD_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(sigret)), C.size_t(siglen), (*C.uchar)(unsafe.Pointer(tbs)), C.size_t(tbslen)) + if r0 != 1 { + err = newError("EVP_DigestVerify") + } + return +} + +func EVP_DigestVerifyFinal(ctx EVP_MD_CTX_PTR, sig *byte, siglen int) (err error) { + r0 := C.EVP_DigestVerifyFinal(C.EVP_MD_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(sig)), C.size_t(siglen)) + if r0 != 1 { + err = newError("EVP_DigestVerifyFinal") + } + return +} + +func EVP_DigestVerifyInit(ctx EVP_MD_CTX_PTR, pctx *EVP_PKEY_CTX_PTR, typ EVP_MD_PTR, e ENGINE_PTR, pkey EVP_PKEY_PTR) (err error) { + r0 := C.EVP_DigestVerifyInit(C.EVP_MD_CTX_PTR(ctx), (*C.EVP_PKEY_CTX_PTR)(unsafe.Pointer(pctx)), C.EVP_MD_PTR(typ), C.ENGINE_PTR(e), C.EVP_PKEY_PTR(pkey)) + if r0 != 1 { + err = newError("EVP_DigestVerifyInit") + } + return +} + +func EVP_EncryptFinal_ex(ctx EVP_CIPHER_CTX_PTR, out *byte, outl *int32) (err error) { + r0 := C.EVP_EncryptFinal_ex(C.EVP_CIPHER_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(out)), (*C.int)(unsafe.Pointer(outl))) + if r0 != 1 { + err = newError("EVP_EncryptFinal_ex") + } + return +} + +func EVP_EncryptInit_ex(ctx EVP_CIPHER_CTX_PTR, typ EVP_CIPHER_PTR, impl ENGINE_PTR, key *byte, iv *byte) (err error) { + r0 := C.EVP_EncryptInit_ex(C.EVP_CIPHER_CTX_PTR(ctx), C.EVP_CIPHER_PTR(typ), C.ENGINE_PTR(impl), (*C.uchar)(unsafe.Pointer(key)), (*C.uchar)(unsafe.Pointer(iv))) + if r0 != 1 { + err = newError("EVP_EncryptInit_ex") + } + return +} + +func EVP_EncryptUpdate(ctx EVP_CIPHER_CTX_PTR, out *byte, outl *int32, in *byte, inl int32) (err error) { + r0 := C.EVP_EncryptUpdate(C.EVP_CIPHER_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(out)), (*C.int)(unsafe.Pointer(outl)), (*C.uchar)(unsafe.Pointer(in)), C.int(inl)) + if r0 != 1 { + err = newError("EVP_EncryptUpdate") + } + return +} + +func EVP_KDF_CTX_free(ctx EVP_KDF_CTX_PTR) { + C.EVP_KDF_CTX_free(C.EVP_KDF_CTX_PTR(ctx)) +} + +func EVP_KDF_CTX_get_kdf_size(ctx EVP_KDF_CTX_PTR) (_r0 int, err error) { + r0 := C.EVP_KDF_CTX_get_kdf_size(C.EVP_KDF_CTX_PTR(ctx)) + _r0 = int(r0) + if _r0 == 0 { + err = newError("EVP_KDF_CTX_get_kdf_size") + } + return +} + +func EVP_KDF_CTX_new(kdf EVP_KDF_PTR) (_r0 EVP_KDF_CTX_PTR, err error) { + r0 := C.EVP_KDF_CTX_new(C.EVP_KDF_PTR(kdf)) + _r0 = EVP_KDF_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_KDF_CTX_new") + } + return +} + +func EVP_KDF_CTX_set_params(ctx EVP_KDF_CTX_PTR, params OSSL_PARAM_PTR) (err error) { + r0 := C.EVP_KDF_CTX_set_params(C.EVP_KDF_CTX_PTR(ctx), C.OSSL_PARAM_PTR(params)) + if r0 != 1 { + err = newError("EVP_KDF_CTX_set_params") + } + return +} + +func EVP_KDF_derive(ctx EVP_KDF_CTX_PTR, key *byte, keylen int, params OSSL_PARAM_PTR) (err error) { + r0 := C.EVP_KDF_derive(C.EVP_KDF_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(key)), C.size_t(keylen), C.OSSL_PARAM_PTR(params)) + if r0 != 1 { + err = newError("EVP_KDF_derive") + } + return +} + +func EVP_KDF_fetch(libctx OSSL_LIB_CTX_PTR, algorithm *byte, properties *byte) (_r0 EVP_KDF_PTR, err error) { + r0 := C.EVP_KDF_fetch(C.OSSL_LIB_CTX_PTR(libctx), (*C.char)(unsafe.Pointer(algorithm)), (*C.char)(unsafe.Pointer(properties))) + _r0 = EVP_KDF_PTR(r0) + if _r0 == nil { + err = newError("EVP_KDF_fetch") + } + return +} + +func EVP_KDF_free(kdf EVP_KDF_PTR) { + C.EVP_KDF_free(C.EVP_KDF_PTR(kdf)) +} + +func EVP_MAC_CTX_dup(arg0 EVP_MAC_CTX_PTR) (_r0 EVP_MAC_CTX_PTR, err error) { + r0 := C.EVP_MAC_CTX_dup(C.EVP_MAC_CTX_PTR(arg0)) + _r0 = EVP_MAC_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_MAC_CTX_dup") + } + return +} + +func EVP_MAC_CTX_free(arg0 EVP_MAC_CTX_PTR) { + C.EVP_MAC_CTX_free(C.EVP_MAC_CTX_PTR(arg0)) +} + +func EVP_MAC_CTX_new(arg0 EVP_MAC_PTR) (_r0 EVP_MAC_CTX_PTR, err error) { + r0 := C.EVP_MAC_CTX_new(C.EVP_MAC_PTR(arg0)) + _r0 = EVP_MAC_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_MAC_CTX_new") + } + return +} + +func EVP_MAC_CTX_set_params(ctx EVP_MAC_CTX_PTR, params OSSL_PARAM_PTR) (err error) { + r0 := C.EVP_MAC_CTX_set_params(C.EVP_MAC_CTX_PTR(ctx), C.OSSL_PARAM_PTR(params)) + if r0 != 1 { + err = newError("EVP_MAC_CTX_set_params") + } + return +} + +func EVP_MAC_fetch(ctx OSSL_LIB_CTX_PTR, algorithm *byte, properties *byte) (_r0 EVP_MAC_PTR, err error) { + r0 := C.EVP_MAC_fetch(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(algorithm)), (*C.char)(unsafe.Pointer(properties))) + _r0 = EVP_MAC_PTR(r0) + if _r0 == nil { + err = newError("EVP_MAC_fetch") + } + return +} + +func EVP_MAC_final(ctx EVP_MAC_CTX_PTR, out *byte, outl *int, outsize int) (err error) { + r0 := C.EVP_MAC_final(C.EVP_MAC_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(out)), (*C.size_t)(unsafe.Pointer(outl)), C.size_t(outsize)) + if r0 != 1 { + err = newError("EVP_MAC_final") + } + return +} + +func EVP_MAC_init(ctx EVP_MAC_CTX_PTR, key *byte, keylen int, params OSSL_PARAM_PTR) (err error) { + r0 := C.EVP_MAC_init(C.EVP_MAC_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(key)), C.size_t(keylen), C.OSSL_PARAM_PTR(params)) + if r0 != 1 { + err = newError("EVP_MAC_init") + } + return +} + +func EVP_MAC_update(ctx EVP_MAC_CTX_PTR, data *byte, datalen int) (err error) { + r0 := C.EVP_MAC_update(C.EVP_MAC_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(data)), C.size_t(datalen)) + if r0 != 1 { + err = newError("EVP_MAC_update") + } + return +} + +func EVP_MD_CTX_copy(out EVP_MD_CTX_PTR, in EVP_MD_CTX_PTR) (err error) { + r0 := C.EVP_MD_CTX_copy(C.EVP_MD_CTX_PTR(out), C.EVP_MD_CTX_PTR(in)) + if r0 != 1 { + err = newError("EVP_MD_CTX_copy") + } + return +} + +func EVP_MD_CTX_copy_ex(out EVP_MD_CTX_PTR, in EVP_MD_CTX_PTR) (err error) { + r0 := C.EVP_MD_CTX_copy_ex(C.EVP_MD_CTX_PTR(out), C.EVP_MD_CTX_PTR(in)) + if r0 != 1 { + err = newError("EVP_MD_CTX_copy_ex") + } + return +} + +func _EVP_MD_CTX_create() (_r0 EVP_MD_CTX_PTR, err error) { + r0 := C.EVP_MD_CTX_create() + _r0 = EVP_MD_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_MD_CTX_create") + } + return +} + +func _EVP_MD_CTX_destroy(ctx EVP_MD_CTX_PTR) { + C.EVP_MD_CTX_destroy(C.EVP_MD_CTX_PTR(ctx)) +} + +func _EVP_MD_CTX_free(ctx EVP_MD_CTX_PTR) { + C.EVP_MD_CTX_free(C.EVP_MD_CTX_PTR(ctx)) +} + +func _EVP_MD_CTX_new() (_r0 EVP_MD_CTX_PTR, err error) { + r0 := C.EVP_MD_CTX_new() + _r0 = EVP_MD_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_MD_CTX_new") + } + return +} + +func _EVP_MD_block_size(md EVP_MD_PTR) (_r0 int32) { + r0 := C.EVP_MD_block_size(C.EVP_MD_PTR(md)) + _r0 = int32(r0) + return +} + +func EVP_MD_fetch(ctx OSSL_LIB_CTX_PTR, algorithm *byte, properties *byte) (_r0 EVP_MD_PTR, err error) { + r0 := C.EVP_MD_fetch(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(algorithm)), (*C.char)(unsafe.Pointer(properties))) + _r0 = EVP_MD_PTR(r0) + if _r0 == nil { + err = newError("EVP_MD_fetch") + } + return +} + +func EVP_MD_free(md EVP_MD_PTR) { + C.EVP_MD_free(C.EVP_MD_PTR(md)) +} + +func EVP_MD_get0_name(md EVP_MD_PTR) (_r0 *byte) { + r0 := C.EVP_MD_get0_name(C.EVP_MD_PTR(md)) + _r0 = (*byte)(unsafe.Pointer(r0)) + return +} + +func EVP_MD_get0_provider(md EVP_MD_PTR) (_r0 OSSL_PROVIDER_PTR, err error) { + r0 := C.EVP_MD_get0_provider(C.EVP_MD_PTR(md)) + _r0 = OSSL_PROVIDER_PTR(r0) + if _r0 == nil { + err = newError("EVP_MD_get0_provider") + } + return +} + +func _EVP_MD_get_block_size(md EVP_MD_PTR) (_r0 int32) { + r0 := C.EVP_MD_get_block_size(C.EVP_MD_PTR(md)) + _r0 = int32(r0) + return +} + +func _EVP_MD_get_size(md EVP_MD_PTR) (_r0 int32) { + r0 := C.EVP_MD_get_size(C.EVP_MD_PTR(md)) + _r0 = int32(r0) + return +} + +func _EVP_MD_size(md EVP_MD_PTR) (_r0 int32) { + r0 := C.EVP_MD_size(C.EVP_MD_PTR(md)) + _r0 = int32(r0) + return +} + +func EVP_PKEY_CTX_add1_hkdf_info(arg0 EVP_PKEY_CTX_PTR, arg1 *byte, arg2 int32) (err error) { + r0 := C.EVP_PKEY_CTX_add1_hkdf_info(C.EVP_PKEY_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), C.int(arg2)) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_add1_hkdf_info") + } + return +} + +func EVP_PKEY_CTX_ctrl(ctx EVP_PKEY_CTX_PTR, keytype int32, optype int32, cmd int32, p1 int32, p2 unsafe.Pointer) (err error) { + r0 := C.EVP_PKEY_CTX_ctrl(C.EVP_PKEY_CTX_PTR(ctx), C.int(keytype), C.int(optype), C.int(cmd), C.int(p1), p2) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_ctrl") + } + return +} + +func EVP_PKEY_CTX_free(arg0 EVP_PKEY_CTX_PTR) { + C.EVP_PKEY_CTX_free(C.EVP_PKEY_CTX_PTR(arg0)) +} + +func EVP_PKEY_CTX_new(arg0 EVP_PKEY_PTR, arg1 ENGINE_PTR) (_r0 EVP_PKEY_CTX_PTR, err error) { + r0 := C.EVP_PKEY_CTX_new(C.EVP_PKEY_PTR(arg0), C.ENGINE_PTR(arg1)) + _r0 = EVP_PKEY_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_CTX_new") + } + return +} + +func EVP_PKEY_CTX_new_from_pkey(libctx OSSL_LIB_CTX_PTR, pkey EVP_PKEY_PTR, propquery *byte) (_r0 EVP_PKEY_CTX_PTR, err error) { + r0 := C.EVP_PKEY_CTX_new_from_pkey(C.OSSL_LIB_CTX_PTR(libctx), C.EVP_PKEY_PTR(pkey), (*C.char)(unsafe.Pointer(propquery))) + _r0 = EVP_PKEY_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_CTX_new_from_pkey") + } + return +} + +func EVP_PKEY_CTX_new_id(id int32, e ENGINE_PTR) (_r0 EVP_PKEY_CTX_PTR, err error) { + r0 := C.EVP_PKEY_CTX_new_id(C.int(id), C.ENGINE_PTR(e)) + _r0 = EVP_PKEY_CTX_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_CTX_new_id") + } + return +} + +func EVP_PKEY_CTX_set0_rsa_oaep_label(ctx EVP_PKEY_CTX_PTR, label unsafe.Pointer, len int32) (err error) { + r0 := C.EVP_PKEY_CTX_set0_rsa_oaep_label(C.EVP_PKEY_CTX_PTR(ctx), label, C.int(len)) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_set0_rsa_oaep_label") + } + return +} + +func EVP_PKEY_CTX_set1_hkdf_key(arg0 EVP_PKEY_CTX_PTR, arg1 *byte, arg2 int32) (err error) { + r0 := C.EVP_PKEY_CTX_set1_hkdf_key(C.EVP_PKEY_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), C.int(arg2)) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_set1_hkdf_key") + } + return +} + +func EVP_PKEY_CTX_set1_hkdf_salt(arg0 EVP_PKEY_CTX_PTR, arg1 *byte, arg2 int32) (err error) { + r0 := C.EVP_PKEY_CTX_set1_hkdf_salt(C.EVP_PKEY_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), C.int(arg2)) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_set1_hkdf_salt") + } + return +} + +func EVP_PKEY_CTX_set_hkdf_md(arg0 EVP_PKEY_CTX_PTR, arg1 EVP_MD_PTR) (err error) { + r0 := C.EVP_PKEY_CTX_set_hkdf_md(C.EVP_PKEY_CTX_PTR(arg0), C.EVP_MD_PTR(arg1)) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_set_hkdf_md") + } + return +} + +func EVP_PKEY_CTX_set_hkdf_mode(arg0 EVP_PKEY_CTX_PTR, arg1 int32) (err error) { + r0 := C.EVP_PKEY_CTX_set_hkdf_mode(C.EVP_PKEY_CTX_PTR(arg0), C.int(arg1)) + if r0 != 1 { + err = newError("EVP_PKEY_CTX_set_hkdf_mode") + } + return +} + +func EVP_PKEY_Q_keygen_EC(ctx OSSL_LIB_CTX_PTR, propq *byte, typ *byte, arg1 *byte) (_r0 EVP_PKEY_PTR, err error) { + r0 := C.EVP_PKEY_Q_keygen_EC(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(propq)), (*C.char)(unsafe.Pointer(typ)), (*C.char)(unsafe.Pointer(arg1))) + _r0 = EVP_PKEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_Q_keygen_EC") + } + return +} + +func EVP_PKEY_Q_keygen_ED25519(ctx OSSL_LIB_CTX_PTR, propq *byte, typ *byte) (_r0 EVP_PKEY_PTR, err error) { + r0 := C.EVP_PKEY_Q_keygen_ED25519(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(propq)), (*C.char)(unsafe.Pointer(typ))) + _r0 = EVP_PKEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_Q_keygen_ED25519") + } + return +} + +func EVP_PKEY_Q_keygen_RSA(ctx OSSL_LIB_CTX_PTR, propq *byte, typ *byte, arg1 int) (_r0 EVP_PKEY_PTR, err error) { + r0 := C.EVP_PKEY_Q_keygen_RSA(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(propq)), (*C.char)(unsafe.Pointer(typ)), C.size_t(arg1)) + _r0 = EVP_PKEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_Q_keygen_RSA") + } + return +} + +func EVP_PKEY_assign(pkey EVP_PKEY_PTR, typ int32, key unsafe.Pointer) (err error) { + r0 := C.EVP_PKEY_assign(C.EVP_PKEY_PTR(pkey), C.int(typ), key) + if r0 != 1 { + err = newError("EVP_PKEY_assign") + } + return +} + +func _EVP_PKEY_bits(pkey EVP_PKEY_PTR) (_r0 int32) { + r0 := C.EVP_PKEY_bits(C.EVP_PKEY_PTR(pkey)) + _r0 = int32(r0) + return +} + +func EVP_PKEY_decrypt(arg0 EVP_PKEY_CTX_PTR, arg1 *byte, arg2 *int, arg3 *byte, arg4 int) (err error) { + r0 := C.EVP_PKEY_decrypt(C.EVP_PKEY_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), (*C.size_t)(unsafe.Pointer(arg2)), (*C.uchar)(unsafe.Pointer(arg3)), C.size_t(arg4)) + if r0 != 1 { + err = newError("EVP_PKEY_decrypt") + } + return +} + +func EVP_PKEY_decrypt_init(arg0 EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_decrypt_init(C.EVP_PKEY_CTX_PTR(arg0)) + if r0 != 1 { + err = newError("EVP_PKEY_decrypt_init") + } + return +} + +func EVP_PKEY_derive(ctx EVP_PKEY_CTX_PTR, key *byte, keylen *int) (err error) { + r0 := C.EVP_PKEY_derive(C.EVP_PKEY_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(key)), (*C.size_t)(unsafe.Pointer(keylen))) + if r0 != 1 { + err = newError("EVP_PKEY_derive") + } + return +} + +func EVP_PKEY_derive_init(ctx EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_derive_init(C.EVP_PKEY_CTX_PTR(ctx)) + if r0 != 1 { + err = newError("EVP_PKEY_derive_init") + } + return +} + +func EVP_PKEY_derive_set_peer(ctx EVP_PKEY_CTX_PTR, peer EVP_PKEY_PTR) (err error) { + r0 := C.EVP_PKEY_derive_set_peer(C.EVP_PKEY_CTX_PTR(ctx), C.EVP_PKEY_PTR(peer)) + if r0 != 1 { + err = newError("EVP_PKEY_derive_set_peer") + } + return +} + +func EVP_PKEY_encrypt(arg0 EVP_PKEY_CTX_PTR, arg1 *byte, arg2 *int, arg3 *byte, arg4 int) (err error) { + r0 := C.EVP_PKEY_encrypt(C.EVP_PKEY_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), (*C.size_t)(unsafe.Pointer(arg2)), (*C.uchar)(unsafe.Pointer(arg3)), C.size_t(arg4)) + if r0 != 1 { + err = newError("EVP_PKEY_encrypt") + } + return +} + +func EVP_PKEY_encrypt_init(arg0 EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_encrypt_init(C.EVP_PKEY_CTX_PTR(arg0)) + if r0 != 1 { + err = newError("EVP_PKEY_encrypt_init") + } + return +} + +func EVP_PKEY_free(key EVP_PKEY_PTR) { + C.EVP_PKEY_free(C.EVP_PKEY_PTR(key)) +} + +func EVP_PKEY_fromdata(ctx EVP_PKEY_CTX_PTR, pkey *EVP_PKEY_PTR, selection int32, params OSSL_PARAM_PTR) (err error) { + r0 := C.EVP_PKEY_fromdata(C.EVP_PKEY_CTX_PTR(ctx), (*C.EVP_PKEY_PTR)(unsafe.Pointer(pkey)), C.int(selection), C.OSSL_PARAM_PTR(params)) + if r0 != 1 { + err = newError("EVP_PKEY_fromdata") + } + return +} + +func EVP_PKEY_fromdata_init(ctx EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_fromdata_init(C.EVP_PKEY_CTX_PTR(ctx)) + if r0 != 1 { + err = newError("EVP_PKEY_fromdata_init") + } + return +} + +func EVP_PKEY_get0(pkey EVP_PKEY_PTR) (_r0 unsafe.Pointer, err error) { + r0 := C.EVP_PKEY_get0(C.EVP_PKEY_PTR(pkey)) + _r0 = unsafe.Pointer(r0) + if _r0 == nil { + err = newError("EVP_PKEY_get0") + } + return +} + +func EVP_PKEY_get0_DSA(pkey EVP_PKEY_PTR) (_r0 DSA_PTR, err error) { + r0 := C.EVP_PKEY_get0_DSA(C.EVP_PKEY_PTR(pkey)) + _r0 = DSA_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_get0_DSA") + } + return +} + +func EVP_PKEY_get0_EC_KEY(pkey EVP_PKEY_PTR) (_r0 EC_KEY_PTR, err error) { + r0 := C.EVP_PKEY_get0_EC_KEY(C.EVP_PKEY_PTR(pkey)) + _r0 = EC_KEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_get0_EC_KEY") + } + return +} + +func EVP_PKEY_get1_RSA(pkey EVP_PKEY_PTR) (_r0 RSA_PTR, err error) { + r0 := C.EVP_PKEY_get1_RSA(C.EVP_PKEY_PTR(pkey)) + _r0 = RSA_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_get1_RSA") + } + return +} + +func EVP_PKEY_get1_encoded_public_key(pkey EVP_PKEY_PTR, ppub **byte) (_r0 int, err error) { + r0 := C.EVP_PKEY_get1_encoded_public_key(C.EVP_PKEY_PTR(pkey), (**C.uchar)(unsafe.Pointer(ppub))) + _r0 = int(r0) + if _r0 == 0 { + err = newError("EVP_PKEY_get1_encoded_public_key") + } + return +} + +func _EVP_PKEY_get_bits(pkey EVP_PKEY_PTR) (_r0 int32) { + r0 := C.EVP_PKEY_get_bits(C.EVP_PKEY_PTR(pkey)) + _r0 = int32(r0) + return +} + +func EVP_PKEY_get_bn_param(pkey EVP_PKEY_PTR, key_name *byte, bn *BIGNUM_PTR) (err error) { + r0 := C.EVP_PKEY_get_bn_param(C.EVP_PKEY_PTR(pkey), (*C.char)(unsafe.Pointer(key_name)), (*C.BIGNUM_PTR)(unsafe.Pointer(bn))) + if r0 != 1 { + err = newError("EVP_PKEY_get_bn_param") + } + return +} + +func EVP_PKEY_get_raw_private_key(pkey EVP_PKEY_PTR, priv *byte, len *int) (err error) { + r0 := C.EVP_PKEY_get_raw_private_key(C.EVP_PKEY_PTR(pkey), (*C.uchar)(unsafe.Pointer(priv)), (*C.size_t)(unsafe.Pointer(len))) + if r0 != 1 { + err = newError("EVP_PKEY_get_raw_private_key") + } + return +} + +func EVP_PKEY_get_raw_public_key(pkey EVP_PKEY_PTR, pub *byte, len *int) (err error) { + r0 := C.EVP_PKEY_get_raw_public_key(C.EVP_PKEY_PTR(pkey), (*C.uchar)(unsafe.Pointer(pub)), (*C.size_t)(unsafe.Pointer(len))) + if r0 != 1 { + err = newError("EVP_PKEY_get_raw_public_key") + } + return +} + +func _EVP_PKEY_get_size(pkey EVP_PKEY_PTR) (_r0 int32) { + r0 := C.EVP_PKEY_get_size(C.EVP_PKEY_PTR(pkey)) + _r0 = int32(r0) + return +} + +func EVP_PKEY_keygen(ctx EVP_PKEY_CTX_PTR, ppkey *EVP_PKEY_PTR) (err error) { + r0 := C.EVP_PKEY_keygen(C.EVP_PKEY_CTX_PTR(ctx), (*C.EVP_PKEY_PTR)(unsafe.Pointer(ppkey))) + if r0 != 1 { + err = newError("EVP_PKEY_keygen") + } + return +} + +func EVP_PKEY_keygen_init(ctx EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_keygen_init(C.EVP_PKEY_CTX_PTR(ctx)) + if r0 != 1 { + err = newError("EVP_PKEY_keygen_init") + } + return +} + +func EVP_PKEY_new() (_r0 EVP_PKEY_PTR, err error) { + r0 := C.EVP_PKEY_new() + _r0 = EVP_PKEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_new") + } + return +} + +func EVP_PKEY_new_raw_private_key(typ int32, e ENGINE_PTR, key *byte, keylen int) (_r0 EVP_PKEY_PTR, err error) { + r0 := C.EVP_PKEY_new_raw_private_key(C.int(typ), C.ENGINE_PTR(e), (*C.uchar)(unsafe.Pointer(key)), C.size_t(keylen)) + _r0 = EVP_PKEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_new_raw_private_key") + } + return +} + +func EVP_PKEY_new_raw_public_key(typ int32, e ENGINE_PTR, key *byte, keylen int) (_r0 EVP_PKEY_PTR, err error) { + r0 := C.EVP_PKEY_new_raw_public_key(C.int(typ), C.ENGINE_PTR(e), (*C.uchar)(unsafe.Pointer(key)), C.size_t(keylen)) + _r0 = EVP_PKEY_PTR(r0) + if _r0 == nil { + err = newError("EVP_PKEY_new_raw_public_key") + } + return +} + +func EVP_PKEY_paramgen(ctx EVP_PKEY_CTX_PTR, ppkey *EVP_PKEY_PTR) (err error) { + r0 := C.EVP_PKEY_paramgen(C.EVP_PKEY_CTX_PTR(ctx), (*C.EVP_PKEY_PTR)(unsafe.Pointer(ppkey))) + if r0 != 1 { + err = newError("EVP_PKEY_paramgen") + } + return +} + +func EVP_PKEY_paramgen_init(ctx EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_paramgen_init(C.EVP_PKEY_CTX_PTR(ctx)) + if r0 != 1 { + err = newError("EVP_PKEY_paramgen_init") + } + return +} + +func EVP_PKEY_set1_EC_KEY(pkey EVP_PKEY_PTR, key EC_KEY_PTR) (err error) { + r0 := C.EVP_PKEY_set1_EC_KEY(C.EVP_PKEY_PTR(pkey), C.EC_KEY_PTR(key)) + if r0 != 1 { + err = newError("EVP_PKEY_set1_EC_KEY") + } + return +} + +func EVP_PKEY_set1_encoded_public_key(pkey EVP_PKEY_PTR, pub *byte, publen int) (err error) { + r0 := C.EVP_PKEY_set1_encoded_public_key(C.EVP_PKEY_PTR(pkey), (*C.uchar)(unsafe.Pointer(pub)), C.size_t(publen)) + if r0 != 1 { + err = newError("EVP_PKEY_set1_encoded_public_key") + } + return +} + +func EVP_PKEY_sign(arg0 EVP_PKEY_CTX_PTR, arg1 *byte, arg2 *int, arg3 *byte, arg4 int) (err error) { + r0 := C.EVP_PKEY_sign(C.EVP_PKEY_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), (*C.size_t)(unsafe.Pointer(arg2)), (*C.uchar)(unsafe.Pointer(arg3)), C.size_t(arg4)) + if r0 != 1 { + err = newError("EVP_PKEY_sign") + } + return +} + +func EVP_PKEY_sign_init(arg0 EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_sign_init(C.EVP_PKEY_CTX_PTR(arg0)) + if r0 != 1 { + err = newError("EVP_PKEY_sign_init") + } + return +} + +func _EVP_PKEY_size(pkey EVP_PKEY_PTR) (_r0 int32) { + r0 := C.EVP_PKEY_size(C.EVP_PKEY_PTR(pkey)) + _r0 = int32(r0) + return +} + +func EVP_PKEY_up_ref(key EVP_PKEY_PTR) (err error) { + r0 := C.EVP_PKEY_up_ref(C.EVP_PKEY_PTR(key)) + if r0 != 1 { + err = newError("EVP_PKEY_up_ref") + } + return +} + +func EVP_PKEY_verify(ctx EVP_PKEY_CTX_PTR, sig *byte, siglen int, tbs *byte, tbslen int) (err error) { + r0 := C.EVP_PKEY_verify(C.EVP_PKEY_CTX_PTR(ctx), (*C.uchar)(unsafe.Pointer(sig)), C.size_t(siglen), (*C.uchar)(unsafe.Pointer(tbs)), C.size_t(tbslen)) + if r0 != 1 { + err = newError("EVP_PKEY_verify") + } + return +} + +func EVP_PKEY_verify_init(arg0 EVP_PKEY_CTX_PTR) (err error) { + r0 := C.EVP_PKEY_verify_init(C.EVP_PKEY_CTX_PTR(arg0)) + if r0 != 1 { + err = newError("EVP_PKEY_verify_init") + } + return +} + +func EVP_SIGNATURE_fetch(ctx OSSL_LIB_CTX_PTR, algorithm *byte, properties *byte) (_r0 EVP_SIGNATURE_PTR, err error) { + r0 := C.EVP_SIGNATURE_fetch(C.OSSL_LIB_CTX_PTR(ctx), (*C.char)(unsafe.Pointer(algorithm)), (*C.char)(unsafe.Pointer(properties))) + _r0 = EVP_SIGNATURE_PTR(r0) + if _r0 == nil { + err = newError("EVP_SIGNATURE_fetch") + } + return +} + +func EVP_SIGNATURE_free(signature EVP_SIGNATURE_PTR) { + C.EVP_SIGNATURE_free(C.EVP_SIGNATURE_PTR(signature)) +} + +func EVP_aes_128_cbc() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_128_cbc() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_128_ctr() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_128_ctr() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_128_ecb() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_128_ecb() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_128_gcm() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_128_gcm() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_192_cbc() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_192_cbc() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_192_ctr() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_192_ctr() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_192_ecb() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_192_ecb() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_192_gcm() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_192_gcm() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_256_cbc() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_256_cbc() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_256_ctr() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_256_ctr() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_256_ecb() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_256_ecb() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_aes_256_gcm() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_aes_256_gcm() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_default_properties_enable_fips(libctx OSSL_LIB_CTX_PTR, enable int32) (err error) { + r0 := C.EVP_default_properties_enable_fips(C.OSSL_LIB_CTX_PTR(libctx), C.int(enable)) + if r0 != 1 { + err = newError("EVP_default_properties_enable_fips") + } + return +} + +func EVP_default_properties_is_fips_enabled(libctx OSSL_LIB_CTX_PTR) (_r0 int32) { + r0 := C.EVP_default_properties_is_fips_enabled(C.OSSL_LIB_CTX_PTR(libctx)) + _r0 = int32(r0) + return +} + +func EVP_des_cbc() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_des_cbc() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_des_ecb() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_des_ecb() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_des_ede3_cbc() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_des_ede3_cbc() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_des_ede3_ecb() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_des_ede3_ecb() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_md4() (_r0 EVP_MD_PTR) { + r0 := C.EVP_md4() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_md5() (_r0 EVP_MD_PTR) { + r0 := C.EVP_md5() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_md5_sha1() (_r0 EVP_MD_PTR) { + r0 := C.EVP_md5_sha1() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_rc4() (_r0 EVP_CIPHER_PTR) { + r0 := C.EVP_rc4() + _r0 = EVP_CIPHER_PTR(r0) + return +} + +func EVP_sha1() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha1() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha224() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha224() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha256() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha256() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha384() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha384() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha3_224() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha3_224() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha3_256() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha3_256() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha3_384() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha3_384() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha3_512() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha3_512() + _r0 = EVP_MD_PTR(r0) + return +} + +func EVP_sha512() (_r0 EVP_MD_PTR) { + r0 := C.EVP_sha512() + _r0 = EVP_MD_PTR(r0) + return +} + +func FIPS_mode() (_r0 int32) { + r0 := C.FIPS_mode() + _r0 = int32(r0) + return +} + +func FIPS_mode_set(r int32) (err error) { + r0 := C.FIPS_mode_set(C.int(r)) + if r0 != 1 { + err = newError("FIPS_mode_set") + } + return +} + +func HMAC_CTX_cleanup(arg0 HMAC_CTX_PTR) { + C.HMAC_CTX_cleanup(C.HMAC_CTX_PTR(arg0)) +} + +func HMAC_CTX_copy(dest HMAC_CTX_PTR, src HMAC_CTX_PTR) (err error) { + r0 := C.HMAC_CTX_copy(C.HMAC_CTX_PTR(dest), C.HMAC_CTX_PTR(src)) + if r0 != 1 { + err = newError("HMAC_CTX_copy") + } + return +} + +func HMAC_CTX_free(arg0 HMAC_CTX_PTR) { + C.HMAC_CTX_free(C.HMAC_CTX_PTR(arg0)) +} + +func HMAC_CTX_init(arg0 HMAC_CTX_PTR) { + C.HMAC_CTX_init(C.HMAC_CTX_PTR(arg0)) +} + +func HMAC_CTX_new() (_r0 HMAC_CTX_PTR, err error) { + r0 := C.HMAC_CTX_new() + _r0 = HMAC_CTX_PTR(r0) + if _r0 == nil { + err = newError("HMAC_CTX_new") + } + return +} + +func HMAC_Final(arg0 HMAC_CTX_PTR, arg1 *byte, arg2 *uint32) (err error) { + r0 := C.HMAC_Final(C.HMAC_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), (*C.uint)(unsafe.Pointer(arg2))) + if r0 != 1 { + err = newError("HMAC_Final") + } + return +} + +func HMAC_Init_ex(arg0 HMAC_CTX_PTR, arg1 unsafe.Pointer, arg2 int32, arg3 EVP_MD_PTR, arg4 ENGINE_PTR) (err error) { + r0 := C.HMAC_Init_ex(C.HMAC_CTX_PTR(arg0), arg1, C.int(arg2), C.EVP_MD_PTR(arg3), C.ENGINE_PTR(arg4)) + if r0 != 1 { + err = newError("HMAC_Init_ex") + } + return +} + +func HMAC_Update(arg0 HMAC_CTX_PTR, arg1 *byte, arg2 int) (err error) { + r0 := C.HMAC_Update(C.HMAC_CTX_PTR(arg0), (*C.uchar)(unsafe.Pointer(arg1)), C.size_t(arg2)) + if r0 != 1 { + err = newError("HMAC_Update") + } + return +} + +func MD5_Final(md *byte, c MD5_CTX_PTR) (err error) { + r0 := C.MD5_Final((*C.uchar)(unsafe.Pointer(md)), C.MD5_CTX_PTR(c)) + if r0 != 1 { + err = newError("MD5_Final") + } + return +} + +func MD5_Init(c MD5_CTX_PTR) (err error) { + r0 := C.MD5_Init(C.MD5_CTX_PTR(c)) + if r0 != 1 { + err = newError("MD5_Init") + } + return +} + +func MD5_Update(c MD5_CTX_PTR, data unsafe.Pointer, len int) (err error) { + r0 := C.MD5_Update(C.MD5_CTX_PTR(c), data, C.size_t(len)) + if r0 != 1 { + err = newError("MD5_Update") + } + return +} + +func OBJ_nid2sn(n int32) (_r0 *byte) { + r0 := C.OBJ_nid2sn(C.int(n)) + _r0 = (*byte)(unsafe.Pointer(r0)) + return +} + +func OPENSSL_add_all_algorithms_conf() { + C.OPENSSL_add_all_algorithms_conf() +} + +func OPENSSL_init() { + C.OPENSSL_init() +} + +func OPENSSL_init_crypto(ops uint64, settings OPENSSL_INIT_SETTINGS_PTR) (err error) { + r0 := C.OPENSSL_init_crypto(C.uint64_t(ops), C.OPENSSL_INIT_SETTINGS_PTR(settings)) + if r0 != 1 { + err = newError("OPENSSL_init_crypto") + } + return +} + +func OSSL_PARAM_BLD_free(bld OSSL_PARAM_BLD_PTR) { + C.OSSL_PARAM_BLD_free(C.OSSL_PARAM_BLD_PTR(bld)) +} + +func OSSL_PARAM_BLD_new() (_r0 OSSL_PARAM_BLD_PTR, err error) { + r0 := C.OSSL_PARAM_BLD_new() + _r0 = OSSL_PARAM_BLD_PTR(r0) + if _r0 == nil { + err = newError("OSSL_PARAM_BLD_new") + } + return +} + +func OSSL_PARAM_BLD_push_BN(bld OSSL_PARAM_BLD_PTR, key *byte, bn BIGNUM_PTR) (err error) { + r0 := C.OSSL_PARAM_BLD_push_BN(C.OSSL_PARAM_BLD_PTR(bld), (*C.char)(unsafe.Pointer(key)), C.BIGNUM_PTR(bn)) + if r0 != 1 { + err = newError("OSSL_PARAM_BLD_push_BN") + } + return +} + +func OSSL_PARAM_BLD_push_int32(bld OSSL_PARAM_BLD_PTR, key *byte, num int32) (err error) { + r0 := C.OSSL_PARAM_BLD_push_int32(C.OSSL_PARAM_BLD_PTR(bld), (*C.char)(unsafe.Pointer(key)), C.int32_t(num)) + if r0 != 1 { + err = newError("OSSL_PARAM_BLD_push_int32") + } + return +} + +func OSSL_PARAM_BLD_push_octet_string(bld OSSL_PARAM_BLD_PTR, key *byte, buf unsafe.Pointer, bsize int) (err error) { + r0 := C.OSSL_PARAM_BLD_push_octet_string(C.OSSL_PARAM_BLD_PTR(bld), (*C.char)(unsafe.Pointer(key)), buf, C.size_t(bsize)) + if r0 != 1 { + err = newError("OSSL_PARAM_BLD_push_octet_string") + } + return +} + +func OSSL_PARAM_BLD_push_utf8_string(bld OSSL_PARAM_BLD_PTR, key *byte, buf *byte, bsize int) (err error) { + r0 := C.OSSL_PARAM_BLD_push_utf8_string(C.OSSL_PARAM_BLD_PTR(bld), (*C.char)(unsafe.Pointer(key)), (*C.char)(unsafe.Pointer(buf)), C.size_t(bsize)) + if r0 != 1 { + err = newError("OSSL_PARAM_BLD_push_utf8_string") + } + return +} + +func OSSL_PARAM_BLD_to_param(bld OSSL_PARAM_BLD_PTR) (_r0 OSSL_PARAM_PTR, err error) { + r0 := C.OSSL_PARAM_BLD_to_param(C.OSSL_PARAM_BLD_PTR(bld)) + _r0 = OSSL_PARAM_PTR(r0) + if _r0 == nil { + err = newError("OSSL_PARAM_BLD_to_param") + } + return +} + +func OSSL_PARAM_free(p OSSL_PARAM_PTR) { + C.OSSL_PARAM_free(C.OSSL_PARAM_PTR(p)) +} + +func OSSL_PROVIDER_available(libctx OSSL_LIB_CTX_PTR, name *byte) (_r0 int32) { + r0 := C.OSSL_PROVIDER_available(C.OSSL_LIB_CTX_PTR(libctx), (*C.char)(unsafe.Pointer(name))) + _r0 = int32(r0) + return +} + +func OSSL_PROVIDER_get0_name(prov OSSL_PROVIDER_PTR) (_r0 *byte) { + r0 := C.OSSL_PROVIDER_get0_name(C.OSSL_PROVIDER_PTR(prov)) + _r0 = (*byte)(unsafe.Pointer(r0)) + return +} + +func OSSL_PROVIDER_try_load(libctx OSSL_LIB_CTX_PTR, name *byte, retain_fallbacks int32) (_r0 OSSL_PROVIDER_PTR, err error) { + r0 := C.OSSL_PROVIDER_try_load(C.OSSL_LIB_CTX_PTR(libctx), (*C.char)(unsafe.Pointer(name)), C.int(retain_fallbacks)) + _r0 = OSSL_PROVIDER_PTR(r0) + if _r0 == nil { + err = newError("OSSL_PROVIDER_try_load") + } + return +} + +func _OpenSSL_version(typ int32) (_r0 *byte) { + r0 := C.OpenSSL_version(C.int(typ)) + _r0 = (*byte)(unsafe.Pointer(r0)) + return +} + +func PKCS5_PBKDF2_HMAC(pass *byte, passlen int32, salt *byte, saltlen int32, iter int32, digest EVP_MD_PTR, keylen int32, out *byte) (err error) { + r0 := C.PKCS5_PBKDF2_HMAC((*C.char)(unsafe.Pointer(pass)), C.int(passlen), (*C.uchar)(unsafe.Pointer(salt)), C.int(saltlen), C.int(iter), C.EVP_MD_PTR(digest), C.int(keylen), (*C.uchar)(unsafe.Pointer(out))) + if r0 != 1 { + err = newError("PKCS5_PBKDF2_HMAC") + } + return +} + +func RAND_bytes(buf *byte, num int32) (err error) { + r0 := C.RAND_bytes((*C.uchar)(unsafe.Pointer(buf)), C.int(num)) + if r0 != 1 { + err = newError("RAND_bytes") + } + return +} + +func RSA_free(r RSA_PTR) { + C.RSA_free(C.RSA_PTR(r)) +} + +func RSA_get0_crt_params(r RSA_PTR, dmp1 *BIGNUM_PTR, dmq1 *BIGNUM_PTR, iqmp *BIGNUM_PTR) { + C.RSA_get0_crt_params(C.RSA_PTR(r), (*C.BIGNUM_PTR)(unsafe.Pointer(dmp1)), (*C.BIGNUM_PTR)(unsafe.Pointer(dmq1)), (*C.BIGNUM_PTR)(unsafe.Pointer(iqmp))) +} + +func RSA_get0_factors(r RSA_PTR, p *BIGNUM_PTR, q *BIGNUM_PTR) { + C.RSA_get0_factors(C.RSA_PTR(r), (*C.BIGNUM_PTR)(unsafe.Pointer(p)), (*C.BIGNUM_PTR)(unsafe.Pointer(q))) +} + +func RSA_get0_key(r RSA_PTR, n *BIGNUM_PTR, e *BIGNUM_PTR, d *BIGNUM_PTR) { + C.RSA_get0_key(C.RSA_PTR(r), (*C.BIGNUM_PTR)(unsafe.Pointer(n)), (*C.BIGNUM_PTR)(unsafe.Pointer(e)), (*C.BIGNUM_PTR)(unsafe.Pointer(d))) +} + +func RSA_new() (_r0 RSA_PTR, err error) { + r0 := C.RSA_new() + _r0 = RSA_PTR(r0) + if _r0 == nil { + err = newError("RSA_new") + } + return +} + +func RSA_set0_crt_params(r RSA_PTR, dmp1 BIGNUM_PTR, dmq1 BIGNUM_PTR, iqmp BIGNUM_PTR) (err error) { + r0 := C.RSA_set0_crt_params(C.RSA_PTR(r), C.BIGNUM_PTR(dmp1), C.BIGNUM_PTR(dmq1), C.BIGNUM_PTR(iqmp)) + if r0 != 1 { + err = newError("RSA_set0_crt_params") + } + return +} + +func RSA_set0_factors(r RSA_PTR, p BIGNUM_PTR, q BIGNUM_PTR) (err error) { + r0 := C.RSA_set0_factors(C.RSA_PTR(r), C.BIGNUM_PTR(p), C.BIGNUM_PTR(q)) + if r0 != 1 { + err = newError("RSA_set0_factors") + } + return +} + +func RSA_set0_key(r RSA_PTR, n BIGNUM_PTR, e BIGNUM_PTR, d BIGNUM_PTR) (err error) { + r0 := C.RSA_set0_key(C.RSA_PTR(r), C.BIGNUM_PTR(n), C.BIGNUM_PTR(e), C.BIGNUM_PTR(d)) + if r0 != 1 { + err = newError("RSA_set0_key") + } + return +} + +func SHA1_Final(md *byte, c SHA_CTX_PTR) (err error) { + r0 := C.SHA1_Final((*C.uchar)(unsafe.Pointer(md)), C.SHA_CTX_PTR(c)) + if r0 != 1 { + err = newError("SHA1_Final") + } + return +} + +func SHA1_Init(c SHA_CTX_PTR) (err error) { + r0 := C.SHA1_Init(C.SHA_CTX_PTR(c)) + if r0 != 1 { + err = newError("SHA1_Init") + } + return +} + +func SHA1_Update(c SHA_CTX_PTR, data unsafe.Pointer, len int) (err error) { + r0 := C.SHA1_Update(C.SHA_CTX_PTR(c), data, C.size_t(len)) + if r0 != 1 { + err = newError("SHA1_Update") + } + return +} + +func _SSLeay_version(typ int32) (_r0 *byte) { + r0 := C.SSLeay_version(C.int(typ)) + _r0 = (*byte)(unsafe.Pointer(r0)) + return +} + +func BN_expand2(a BIGNUM_PTR, n int32) (_r0 BIGNUM_PTR, err error) { + r0 := C.bn_expand2(C.BIGNUM_PTR(a), C.int(n)) + _r0 = BIGNUM_PTR(r0) + if _r0 == nil { + err = newError("bn_expand2") + } + return +} From 5d8a3b1349bc0d9d5c36f6771d8bc8830bf77605 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 12:04:21 +0100 Subject: [PATCH 04/20] move files from root to the ossl package --- cgo_go124.go => internal/ossl/cgo_go124.go | 6 +-- port_dsa.c => internal/ossl/port_dsa.c | 37 ++++++++++--------- .../ossl/port_evp_md5_sha1.c | 19 +++++----- .../ossl/thread_setup.go | 4 +- .../ossl/thread_setup.h | 0 .../ossl/thread_setup_test.go | 4 +- .../ossl/thread_setup_unix.c | 14 +++---- .../ossl/thread_setup_windows.c | 18 ++++----- 8 files changed, 52 insertions(+), 50 deletions(-) rename cgo_go124.go => internal/ossl/cgo_go124.go (87%) rename port_dsa.c => internal/ossl/port_dsa.c (61%) rename port_evp_md5_sha1.c => internal/ossl/port_evp_md5_sha1.c (86%) rename thread_setup.go => internal/ossl/thread_setup.go (87%) rename thread_setup.h => internal/ossl/thread_setup.h (100%) rename thread_setup_test.go => internal/ossl/thread_setup_test.go (96%) rename thread_setup_unix.c => internal/ossl/thread_setup_unix.c (82%) rename thread_setup_windows.c => internal/ossl/thread_setup_windows.c (75%) diff --git a/cgo_go124.go b/internal/ossl/cgo_go124.go similarity index 87% rename from cgo_go124.go rename to internal/ossl/cgo_go124.go index 933a7518..2da663e2 100644 --- a/cgo_go124.go +++ b/internal/ossl/cgo_go124.go @@ -1,6 +1,6 @@ //go:build go1.24 && !cmd_go_bootstrap -package openssl +package ossl // The following noescape and nocallback directives are used to prevent the Go // compiler from allocating function parameters on the heap. See @@ -13,6 +13,6 @@ package openssl // observed to benefit from these directives, not every function that is merely // expected to meet the noescape/nocallback criteria. -// #cgo noescape go_openssl_RAND_bytes -// #cgo nocallback go_openssl_RAND_bytes +// #cgo noescape RAND_bytes +// #cgo nocallback RAND_bytes import "C" diff --git a/port_dsa.c b/internal/ossl/port_dsa.c similarity index 61% rename from port_dsa.c rename to internal/ossl/port_dsa.c index 5a948eaf..345af5f8 100644 --- a/port_dsa.c +++ b/internal/ossl/port_dsa.c @@ -3,24 +3,25 @@ // on the OpenSSL_1_1_0-stable branch. Only pqg and key getters/setters // are backported. -#include "goopenssl.h" +#include "api.h" +#include struct dsa_st { int _ignored0; long _ignored1; int _ignored2; - GO_BIGNUM_PTR p; - GO_BIGNUM_PTR q; - GO_BIGNUM_PTR g; - GO_BIGNUM_PTR pub_key; - GO_BIGNUM_PTR priv_key; + BIGNUM_PTR p; + BIGNUM_PTR q; + BIGNUM_PTR g; + BIGNUM_PTR pub_key; + BIGNUM_PTR priv_key; // The following members are not used by our backport, // so we don't define them here. }; -void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR dsa, - GO_BIGNUM_PTR *p, GO_BIGNUM_PTR *q, GO_BIGNUM_PTR *g) +void go_openssl_DSA_get0_pqg_backport(const DSA_PTR dsa, + BIGNUM_PTR *p, BIGNUM_PTR *q, BIGNUM_PTR *g) { const struct dsa_st *d = dsa; if (p != NULL) @@ -31,8 +32,8 @@ void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR dsa, *g = d->g; } -int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR dsa, - GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g) +int go_openssl_DSA_set0_pqg_backport(DSA_PTR dsa, + BIGNUM_PTR p, BIGNUM_PTR q, BIGNUM_PTR g) { struct dsa_st *d = dsa; if ((d->p == NULL && p == NULL) @@ -41,23 +42,23 @@ int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR dsa, return 0; if (p != NULL) { - go_openssl_BN_free(d->p); + BN_free(d->p); d->p = p; } if (q != NULL) { - go_openssl_BN_free(d->q); + BN_free(d->q); d->q = q; } if (g != NULL) { - go_openssl_BN_free(d->g); + BN_free(d->g); d->g = g; } return 1; } -void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR dsa, - GO_BIGNUM_PTR *pub_key, GO_BIGNUM_PTR *priv_key) +void go_openssl_DSA_get0_key_backport(const DSA_PTR dsa, + BIGNUM_PTR *pub_key, BIGNUM_PTR *priv_key) { const struct dsa_st *d = dsa; if (pub_key != NULL) @@ -66,18 +67,18 @@ void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR dsa, *priv_key = d->priv_key; } -int go_openssl_DSA_set0_key_backport(GO_DSA_PTR dsa, GO_BIGNUM_PTR pub_key, GO_BIGNUM_PTR priv_key) +int go_openssl_DSA_set0_key_backport(DSA_PTR dsa, BIGNUM_PTR pub_key, BIGNUM_PTR priv_key) { struct dsa_st *d = dsa; if (d->pub_key == NULL && pub_key == NULL) return 0; if (pub_key != NULL) { - go_openssl_BN_free(d->pub_key); + BN_free(d->pub_key); d->pub_key = pub_key; } if (priv_key != NULL) { - go_openssl_BN_free(d->priv_key); + BN_free(d->priv_key); d->priv_key = priv_key; } diff --git a/port_evp_md5_sha1.c b/internal/ossl/port_evp_md5_sha1.c similarity index 86% rename from port_evp_md5_sha1.c rename to internal/ossl/port_evp_md5_sha1.c index 50d49b1f..12f37191 100644 --- a/port_evp_md5_sha1.c +++ b/internal/ossl/port_evp_md5_sha1.c @@ -11,7 +11,8 @@ * https://www.openssl.org/source/license.html */ -#include "goopenssl.h" +#include "api.h" +#include #define NID_md5_sha1 114 @@ -81,24 +82,24 @@ struct md5_sha1_ctx { static int md5_sha1_init(EVP_MD_CTX *ctx) { struct md5_sha1_ctx *mctx = ctx->md_data; - if (!go_openssl_MD5_Init(&mctx->md5)) + if (!MD5_Init(&mctx->md5)) return 0; - return go_openssl_SHA1_Init(&mctx->sha1); + return SHA1_Init(&mctx->sha1); } static int md5_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) { struct md5_sha1_ctx *mctx = ctx->md_data; - if (!go_openssl_MD5_Update(&mctx->md5, data, count)) + if (!MD5_Update(&mctx->md5, data, count)) return 0; - return go_openssl_SHA1_Update(&mctx->sha1, data, count); + return SHA1_Update(&mctx->sha1, data, count); } static int md5_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) { struct md5_sha1_ctx *mctx = ctx->md_data; - if (!go_openssl_MD5_Final(md, &mctx->md5)) + if (!MD5_Final(md, &mctx->md5)) return 0; - return go_openssl_SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); + return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1); } // Change: Removed: @@ -121,6 +122,6 @@ static const EVP_MD md5_sha1_md = { }; // Change: Apply name mangling. -const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void) { - return (const GO_EVP_MD_PTR)&md5_sha1_md; +const EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void) { + return (const EVP_MD_PTR)&md5_sha1_md; } diff --git a/thread_setup.go b/internal/ossl/thread_setup.go similarity index 87% rename from thread_setup.go rename to internal/ossl/thread_setup.go index 5e0da7e3..04bd2413 100644 --- a/thread_setup.go +++ b/internal/ossl/thread_setup.go @@ -1,6 +1,6 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo -package openssl +package ossl // Go wrappers for testing the thread setup code as _test.go files cannot import "C". diff --git a/thread_setup.h b/internal/ossl/thread_setup.h similarity index 100% rename from thread_setup.h rename to internal/ossl/thread_setup.h diff --git a/thread_setup_test.go b/internal/ossl/thread_setup_test.go similarity index 96% rename from thread_setup_test.go rename to internal/ossl/thread_setup_test.go index 57e41aaa..10a70991 100644 --- a/thread_setup_test.go +++ b/internal/ossl/thread_setup_test.go @@ -1,4 +1,4 @@ -package openssl +package ossl import ( "runtime" @@ -28,7 +28,7 @@ func TestThreadCleanup(t *testing.T) { runtime.LockOSThread() // Checking for errors has the side effect of initializing // the thread-local OpenSSL error queue. - _ = newOpenSSLError("") + _ = newError("") }() <-done time.Sleep(100 * time.Millisecond) // Give some time for the thread to terminate. diff --git a/thread_setup_unix.c b/internal/ossl/thread_setup_unix.c similarity index 82% rename from thread_setup_unix.c rename to internal/ossl/thread_setup_unix.c index c837f9cb..b2e5adaf 100644 --- a/thread_setup_unix.c +++ b/internal/ossl/thread_setup_unix.c @@ -1,6 +1,6 @@ //go:build unix -#include "goopenssl.h" +#include "ossl.h" #include "thread_setup.h" #include @@ -22,7 +22,7 @@ static void locking_function(int mode, int n, const char *file, int line) static void thread_id(GO_CRYPTO_THREADID_PTR tid) { - go_openssl_CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); + CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); // OpenSSL fetches the current thread ID whenever it does anything with the // per-thread error state, so this function is guaranteed to be executed at @@ -38,7 +38,7 @@ static void thread_id(GO_CRYPTO_THREADID_PTR tid) static void cleanup_thread_state(void *ignored) { UNUSED(ignored); - go_openssl_ERR_remove_thread_state(NULL); + ERR_remove_thread_state(NULL); // ERR_remove_thread_state(NULL) in turn calls our registered thread_id // callback via CRYPTO_THREADID_current(), which sets the thread-local // variable associated with this destructor to a non-NULL value. We have to @@ -52,13 +52,13 @@ int go_openssl_thread_setup(void) { if (pthread_key_create(&destructor_key, cleanup_thread_state) != 0) return 0; - mutex_buf = malloc(go_openssl_CRYPTO_num_locks()*sizeof(pthread_mutex_t)); + mutex_buf = malloc(CRYPTO_num_locks()*sizeof(pthread_mutex_t)); if (!mutex_buf) return 0; int i; - for (i = 0; i < go_openssl_CRYPTO_num_locks(); i++) + for (i = 0; i < CRYPTO_num_locks(); i++) pthread_mutex_init(&mutex_buf[i], NULL); - go_openssl_CRYPTO_THREADID_set_callback(thread_id); - go_openssl_CRYPTO_set_locking_callback(locking_function); + CRYPTO_THREADID_set_callback(thread_id); + CRYPTO_set_locking_callback(locking_function); return 1; } diff --git a/thread_setup_windows.c b/internal/ossl/thread_setup_windows.c similarity index 75% rename from thread_setup_windows.c rename to internal/ossl/thread_setup_windows.c index 93281d6c..dc76ffd3 100644 --- a/thread_setup_windows.c +++ b/internal/ossl/thread_setup_windows.c @@ -1,6 +1,6 @@ //go:build windows -#include "goopenssl.h" +#include "api.h" #include "thread_setup.h" #include @@ -22,9 +22,9 @@ static void locking_function(int mode, int n, const char *file, int line) ReleaseMutex(mutex_buf[n]); } -static void thread_id(GO_CRYPTO_THREADID_PTR tid) +static void thread_id(CRYPTO_THREADID_PTR tid) { - go_openssl_CRYPTO_THREADID_set_numeric(tid, (unsigned long)GetCurrentThreadId()); + CRYPTO_THREADID_set_numeric(tid, (unsigned long)GetCurrentThreadId()); // OpenSSL fetches the current thread ID whenever it does anything with the // per-thread error state, so this function is guaranteed to be executed at @@ -39,7 +39,7 @@ static void thread_id(GO_CRYPTO_THREADID_PTR tid) static void cleanup_thread_state(void *ignored) { UNUSED(ignored); - go_openssl_ERR_remove_thread_state(NULL); + ERR_remove_thread_state(NULL); } int go_openssl_thread_setup(void) @@ -49,16 +49,16 @@ int go_openssl_thread_setup(void) fls_index = FlsAlloc(cleanup_thread_state); if (fls_index == FLS_OUT_OF_INDEXES) return 0; - mutex_buf = malloc(go_openssl_CRYPTO_num_locks()*sizeof(HANDLE)); + mutex_buf = malloc(CRYPTO_num_locks()*sizeof(HANDLE)); if (!mutex_buf) return 0; int i; - for (i = 0; i < go_openssl_CRYPTO_num_locks(); i++) + for (i = 0; i < CRYPTO_num_locks(); i++) mutex_buf[i] = CreateMutex(NULL, FALSE, NULL); - go_openssl_CRYPTO_set_locking_callback(locking_function); - // go_openssl_CRYPTO_set_id_callback is not strictly needed on Windows + CRYPTO_set_locking_callback(locking_function); + // CRYPTO_set_id_callback is not strictly needed on Windows // as OpenSSL uses GetCurrentThreadId() by default. // But we need to piggyback off the callback for our own purposes. - go_openssl_CRYPTO_THREADID_set_callback(thread_id); + CRYPTO_THREADID_set_callback(thread_id); return 1; } From d00b58065fc76aa082d5f1573e808caeca744e88 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 12:08:09 +0100 Subject: [PATCH 05/20] add extra ossl wrappers --- internal/ossl/ossl.c | 137 +++++++++++++++++++++++++++ internal/ossl/ossl.go | 113 ++++++++++++++++++++++ internal/ossl/ossl_cgo.go | 158 +++++++++++++++++++++++++++++++ internal/ossl/ossl_extra.h | 188 +++++++++++++++++++++++++++++++++++++ 4 files changed, 596 insertions(+) create mode 100644 internal/ossl/ossl.c create mode 100644 internal/ossl/ossl_extra.h diff --git a/internal/ossl/ossl.c b/internal/ossl/ossl.c new file mode 100644 index 00000000..d28f9800 --- /dev/null +++ b/internal/ossl/ossl.c @@ -0,0 +1,137 @@ +//go:build unix || windows + +#ifdef _WIN32 +# include +# define dlsym (void*)GetProcAddress +#else +# include // dlsym +#endif +#include // fprintf + +// go_openssl_fips_enabled returns 1 if FIPS mode is enabled, 0 otherwise. +// As a special case, it returns -1 if it cannot determine if FIPS mode is enabled. +// See openssl.FIPS for details about its implementation. +// +// This function is reimplemented here because openssl.FIPS assumes that +// all the OpenSSL bindings are loaded, that is, go_openssl_load_functions has +// already been called. On the other hand, go_openssl_fips_enabled is called from +// openssl.CheckVersion, which is used to check if a given OpenSSL shared library +// exists and is FIPS compliant. That shared library might not be the one that +// was passed to go_openssl_load_functions, or it might not even have been called at all. +// +// It is written in C because it is not possible to directly call C function pointers +// retrieved using dlsym from Go. +int +go_openssl_fips_enabled(void* handle) +{ + // For OpenSSL 1.x. + int (*FIPS_mode)(void); + FIPS_mode = (int (*)(void))dlsym(handle, "FIPS_mode"); + if (FIPS_mode != NULL) + return FIPS_mode(); + + // For OpenSSL 3.x. + int (*EVP_default_properties_is_fips_enabled)(void*) = (int (*)(void*))dlsym(handle, "EVP_default_properties_is_fips_enabled"); + void *(*EVP_MD_fetch)(void*, const char*, const char*) = (void* (*)(void*, const char*, const char*))dlsym(handle, "EVP_MD_fetch"); + void (*EVP_MD_free)(void*) = (void (*)(void*))dlsym(handle, "EVP_MD_free"); + + if (EVP_default_properties_is_fips_enabled == NULL || EVP_MD_fetch == NULL || EVP_MD_free == NULL) { + // Shouldn't happen, but if it does, we can't determine if FIPS mode is enabled. + return -1; + } + + if (EVP_default_properties_is_fips_enabled(NULL) != 1) + return 0; + + void *md = EVP_MD_fetch(NULL, "SHA2-256", NULL); + if (md == NULL) + return 0; + + EVP_MD_free(md); + return 1; +} + +static unsigned long +version_num(void* handle) +{ + unsigned long (*fn)(void); + // OPENSSL_version_num is defined in OpenSSL 1.1.0 and 1.1.1. + fn = (unsigned long (*)(void))dlsym(handle, "OpenSSL_version_num"); + if (fn != NULL) + return fn(); + + // SSLeay is defined in OpenSSL 1.0.2. + fn = (unsigned long (*)(void))dlsym(handle, "SSLeay"); + if (fn != NULL) + return fn(); + + return 0; +} + +int +go_openssl_version_major(void* handle) +{ + unsigned int (*fn)(void); + // OPENSSL_version_major is supported since OpenSSL 3. + fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_major"); + if (fn != NULL) + return (int)fn(); + + // If OPENSSL_version_major is not defined, try with OpenSSL 1 functions. + unsigned long num = version_num(handle); + if (num < 0x10000000L || num >= 0x20000000L) + return -1; + + return 1; +} + +int +go_openssl_version_minor(void* handle) +{ + unsigned int (*fn)(void); + // OPENSSL_version_minor is supported since OpenSSL 3. + fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_minor"); + if (fn != NULL) + return (int)fn(); + + // If OPENSSL_version_minor is not defined, try with OpenSSL 1 functions. + unsigned long num = version_num(handle); + // OpenSSL version number follows this schema: + // MNNFFPPS: major minor fix patch status. + if (num < 0x10000000L || num >= 0x10200000L) + { + // We only support minor version 0 and 1, + // so there is no need to implement an algorithm + // that decodes the version number into individual components. + return -1; + } + + if (num >= 0x10100000L) + return 1; + + return 0; +} + +int +go_openssl_version_patch(void* handle) +{ + unsigned int (*fn)(void); + // OPENSSL_version_patch is supported since OpenSSL 3. + fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_patch"); + if (fn != NULL) + return (int)fn(); + + // If OPENSSL_version_patch is not defined, try with OpenSSL 1 functions. + unsigned long num = version_num(handle); + // OpenSSL version number follows this schema: + // MNNFFPPS: major minor fix patch status. + if (num < 0x10000000L || num >= 0x10200000L) + { + // We only support minor version 0 and 1, + // so there is no need to implement an algorithm + // that decodes the version number into individual components. + return -1; + } + + return (num >> 12) & 0xff; +} diff --git a/internal/ossl/ossl.go b/internal/ossl/ossl.go index 2d163d1a..a5f669b8 100644 --- a/internal/ossl/ossl.go +++ b/internal/ossl/ossl.go @@ -2,4 +2,117 @@ package ossl +import ( + "errors" + "strconv" + "strings" + "unsafe" +) + //go:generate go run github.com/golang-fips/openssl/v2/internal/mkcgo -out zossl.go --package ossl --lib crypto --include ossl.h api.h + +var vMajor, vMinor, vPatch int + +func LoadLcrypto(handle unsafe.Pointer) { + mkcgoLoad_crypto(handle) + vMajor = Go_openssl_version_major(handle) + vMinor = Go_openssl_version_minor(handle) + vPatch = Go_openssl_version_minor(handle) +} + +func newError(msg string) error { + var b strings.Builder + b.WriteString(msg) + b.WriteString("\nopenssl error(s):") + for { + var ( + e uint64 + file *byte + line int32 + ) + if vMajor == 1 { + e = ERR_get_error_line(&file, &line) + } else { + e = ERR_get_error_all(&file, &line, nil, nil, nil) + } + if e == 0 { + break + } + b.WriteByte('\n') + var buf [256]byte + ERR_error_string_n(e, &buf[0], len(buf)) + b.WriteString(string(buf[:]) + "\n\t" + goString(file) + ":" + strconv.Itoa(int(line))) + } + return errors.New(b.String()) +} + +// goString converts a C null-terminated string to a Go string. +func goString(p *byte) string { + if p == nil { + return "" + } + end := unsafe.Pointer(p) + n := 0 + for *(*byte)(end) != 0 { + end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) + n++ + } + return string(unsafe.Slice(p, n)) +} + +func OpenSSL_version(typ int32) *byte { + if vMajor == 1 && vMinor == 0 { + return _SSLeay_version(typ) + } + return _OpenSSL_version(typ) +} + +func EVP_MD_CTX_free(ctx EVP_MD_CTX_PTR) { + if vMajor == 1 && vMinor == 0 { + _EVP_MD_CTX_destroy(ctx) + } else { + _EVP_MD_CTX_free(ctx) + } +} + +func EVP_MD_CTX_new() (EVP_MD_CTX_PTR, error) { + if vMajor == 1 && vMinor == 0 { + return _EVP_MD_CTX_create() + } + return _EVP_MD_CTX_new() +} + +func EVP_MD_get_size(md EVP_MD_PTR) int32 { + if vMajor == 1 { + return _EVP_MD_size(md) + } + return _EVP_MD_get_size(md) +} + +func EVP_MD_get_block_size(md EVP_MD_PTR) int32 { + if vMajor == 1 { + return _EVP_MD_block_size(md) + } + return _EVP_MD_get_block_size(md) +} + +func EVP_PKEY_get_size(pkey EVP_PKEY_PTR) int32 { + if vMajor == 1 { + return _EVP_PKEY_size(pkey) + } + return _EVP_PKEY_get_size(pkey) +} + +func EVP_PKEY_get_bits(pkey EVP_PKEY_PTR) int32 { + if vMajor == 1 { + return _EVP_PKEY_bits(pkey) + } + return _EVP_PKEY_get_bits(pkey) +} + +func EVP_CIPHER_get_block_size(cipher EVP_CIPHER_PTR) int32 { + if vMajor == 1 { + return _EVP_CIPHER_block_size(cipher) + } + return _EVP_CIPHER_get_block_size(cipher) +} diff --git a/internal/ossl/ossl_cgo.go b/internal/ossl/ossl_cgo.go index 7dd9bedb..04d2d52a 100644 --- a/internal/ossl/ossl_cgo.go +++ b/internal/ossl/ossl_cgo.go @@ -2,7 +2,12 @@ package ossl +/* +#include "ossl_extra.h" +#include +*/ import "C" +import "unsafe" type Point_conversion_form_t = C.point_conversion_form_t @@ -34,3 +39,156 @@ type EVP_KDF_PTR = C.EVP_KDF_PTR type EVP_KDF_CTX_PTR = C.EVP_KDF_CTX_PTR type MD5_CTX_PTR = C.MD5_CTX_PTR type SHA_CTX_PTR = C.SHA_CTX_PTR + +func EVP_EncryptUpdate_wrapper(ctx EVP_CIPHER_CTX_PTR, out *byte, in *byte, inl int32) (err error) { + r0 := C.EVP_EncryptUpdate_wrapper(ctx, (*C.uint8_t)(unsafe.Pointer(out)), (*C.uint8_t)(unsafe.Pointer(in)), C.int32_t(inl)) + if r0 != 1 { + err = newError("EVP_EncryptUpdate_wrapper") + } + return +} + +func EVP_DecryptUpdate_wrapper(ctx EVP_CIPHER_CTX_PTR, out *byte, in *byte, inl int32) (err error) { + r0 := C.EVP_DecryptUpdate_wrapper(ctx, (*C.uint8_t)(unsafe.Pointer(out)), (*C.uint8_t)(unsafe.Pointer(in)), C.int32_t(inl)) + if r0 != 1 { + err = newError("EVP_DecryptUpdate_wrapper") + } + return +} + +func EVP_CipherUpdate_wrapper(ctx EVP_CIPHER_CTX_PTR, out *byte, in *byte, inl int32) (err error) { + r0 := C.EVP_CipherUpdate_wrapper(ctx, (*C.uint8_t)(unsafe.Pointer(out)), (*C.uint8_t)(unsafe.Pointer(in)), C.int32_t(inl)) + if r0 != 1 { + err = newError("EVP_CipherUpdate_wrapper") + } + return +} + +func EVP_CIPHER_CTX_seal_wrapper(ctx EVP_CIPHER_CTX_PTR, out *byte, nonce *byte, in *byte, inl int32, aad *byte, addl int32) (err error) { + r0 := C.EVP_CIPHER_CTX_seal_wrapper(ctx, + (*C.uint8_t)(unsafe.Pointer(out)), + (*C.uint8_t)(unsafe.Pointer(nonce)), + (*C.uint8_t)(unsafe.Pointer(in)), + C.int32_t(inl), + (*C.uint8_t)(unsafe.Pointer(aad)), + C.int32_t(addl), + ) + if r0 != 1 { + err = newError("EVP_CIPHER_CTX_seal_wrapper") + } + return +} + +func EVP_CIPHER_CTX_open_wrapper(ctx EVP_CIPHER_CTX_PTR, out *byte, nonce *byte, in *byte, inl int32, aad *byte, addl int32, tag *byte) (err error) { + r0 := C.EVP_CIPHER_CTX_open_wrapper(ctx, + (*C.uint8_t)(unsafe.Pointer(out)), + (*C.uint8_t)(unsafe.Pointer(nonce)), + (*C.uint8_t)(unsafe.Pointer(in)), + C.int32_t(inl), + (*C.uint8_t)(unsafe.Pointer(aad)), + C.int32_t(addl), + (*C.uint8_t)(unsafe.Pointer(tag)), + ) + if r0 != 1 { + err = newError("EVP_CIPHER_CTX_open_wrapper") + } + return +} + +func DSA_get0_pqg_backport(dsa DSA_PTR, p, q, g *BIGNUM_PTR) { + C.go_openssl_DSA_get0_pqg_backport(dsa, p, q, g) +} + +func DSA_get0_key_backport(dsa DSA_PTR, pub_key, priv_key *BIGNUM_PTR) { + C.go_openssl_DSA_get0_key_backport(dsa, pub_key, priv_key) +} + +func DSA_set0_key_backport(dsa DSA_PTR, pub_key, priv_key BIGNUM_PTR) error { + if C.go_openssl_DSA_set0_key_backport(dsa, pub_key, priv_key) != 1 { + return newError("DSA_set0_key_backport") + } + return nil +} + +func DSA_set0_pqg_backport(dsa DSA_PTR, p, q, g BIGNUM_PTR) error { + if C.go_openssl_DSA_set0_pqg_backport(dsa, p, q, g) != 1 { + return newError("DSA_set0_pqg_backport") + } + return nil +} + +func EVP_md5_sha1_backport() EVP_MD_PTR { + return C.go_openssl_EVP_md5_sha1_backport() +} + +func HashSum(ctx, ctx2 EVP_MD_CTX_PTR, out *byte) error { + if C.go_hash_sum(ctx, ctx2, (*C.uchar)(unsafe.Pointer(out))) != 1 { + return newError("go_hash_sum") + } + return nil +} + +func EVP_PKEY_derive_wrapper(ctx EVP_PKEY_CTX_PTR, key *byte, keylen int) (int, error) { + r := C.EVP_PKEY_derive_wrapper(ctx, (*C.uchar)(unsafe.Pointer(key)), C.size_t(keylen)) + if r.result != 1 { + return 0, newError("EVP_PKEY_derive_wrapper") + } + return int(r.keylen), nil +} + +// Hand-roll custom wrappers for CRYPTO_malloc and CRYPTO_free which cast the +// function pointers to the correct signatures for OpenSSL 1.0.2. + +func CRYPTO_malloc_legacy102(num int32, file *byte, line int32) unsafe.Pointer { + return CRYPTO_malloc(int(num), file, line) +} + +func CRYPTO_free_legacy102(str unsafe.Pointer) { + CRYPTO_free(str, nil, 0) +} + +func EVP_PKEY_get_raw_public_key_wrapper(pkey EVP_PKEY_PTR, out *byte, outlen int) (int, error) { + r := C.EVP_PKEY_get_raw_public_key_wrapper(pkey, (*C.uchar)(unsafe.Pointer(out)), C.size_t(outlen)) + if r.result != 1 { + return 0, newError("EVP_PKEY_get_raw_public_key") + } + return int(r.len), nil +} + +func EVP_PKEY_get_raw_private_key_wrapper(pkey EVP_PKEY_PTR, out *byte, outlen int) (int, error) { + r := C.EVP_PKEY_get_raw_private_key_wrapper(pkey, (*C.uchar)(unsafe.Pointer(out)), C.size_t(outlen)) + if r.result != 1 { + return 0, newError("EVP_PKEY_get_raw_private_key") + } + return int(r.len), nil +} + +func EVP_DigestSign_wrapper(ctx EVP_MD_CTX_PTR, sig *byte, siglen int, msg *byte, msglen int) (int, error) { + r := C.EVP_DigestSign_wrapper(ctx, (*C.uchar)(unsafe.Pointer(sig)), C.size_t(siglen), (*C.uchar)(unsafe.Pointer(msg)), C.size_t(msglen)) + if r.result != 1 { + return 0, newError("EVP_DigestSign") + } + return int(r.siglen), nil +} + +func ThreadSetup() { + if C.go_openssl_thread_setup() != 1 { + panic("go_openssl_thread_setup") + } +} + +func Go_openssl_fips_enabled(handle unsafe.Pointer) int { + return int(C.go_openssl_fips_enabled(handle)) +} + +func Go_openssl_version_major(handle unsafe.Pointer) int { + return int(C.go_openssl_version_major(handle)) +} + +func Go_openssl_version_minor(handle unsafe.Pointer) int { + return int(C.go_openssl_version_minor(handle)) +} + +func Go_openssl_version_patch(handle unsafe.Pointer) int { + return int(C.go_openssl_version_patch(handle)) +} diff --git a/internal/ossl/ossl_extra.h b/internal/ossl/ossl_extra.h new file mode 100644 index 00000000..dd1be420 --- /dev/null +++ b/internal/ossl/ossl_extra.h @@ -0,0 +1,188 @@ +#include "api.h" +#include + +int go_openssl_fips_enabled(void* handle); +int go_openssl_version_major(void* handle); +int go_openssl_version_minor(void* handle); +int go_openssl_version_patch(void* handle); +void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); +int go_openssl_thread_setup(void); +const EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); +void go_openssl_DSA_get0_pqg_backport(const DSA_PTR d, BIGNUM_PTR *p, BIGNUM_PTR *q, BIGNUM_PTR *g); +int go_openssl_DSA_set0_pqg_backport(DSA_PTR d, BIGNUM_PTR p, BIGNUM_PTR q, BIGNUM_PTR g); +void go_openssl_DSA_get0_key_backport(const DSA_PTR d, BIGNUM_PTR *pub_key, BIGNUM_PTR *priv_key); +int go_openssl_DSA_set0_key_backport(DSA_PTR d, BIGNUM_PTR pub_key, BIGNUM_PTR priv_key); + +// These wrappers allocate out_len on the C stack to avoid having to pass a pointer from Go, which would escape to the heap. +// Use them only in situations where the output length can be safely discarded. +static inline int +EVP_EncryptUpdate_wrapper(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, unsigned char *in, int in_len) +{ + int len; + return EVP_EncryptUpdate(ctx, out, &len, in, in_len); +} + +static inline int +EVP_DecryptUpdate_wrapper(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, unsigned char *in, int in_len) +{ + int len; + return EVP_DecryptUpdate(ctx, out, &len, in, in_len); +} + +static inline int +EVP_CipherUpdate_wrapper(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, unsigned char *in, int in_len) +{ + int len; + return EVP_CipherUpdate(ctx, out, &len, in, in_len); +} + + +// These wrappers allocate out_len on the C stack, and check that it matches the expected +// value, to avoid having to pass a pointer from Go, which would escape to the heap. + +static inline int +EVP_CIPHER_CTX_seal_wrapper(EVP_CIPHER_CTX_PTR ctx, + unsigned char *out, + const unsigned char *nonce, + const unsigned char *in, int in_len, + const unsigned char *aad, int aad_len) +{ + if (in_len == 0) in = (const unsigned char *)""; + if (aad_len == 0) aad = (const unsigned char *)""; + + if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) + return 0; + + int discard_len, out_len; + if (EVP_EncryptUpdate(ctx, NULL, &discard_len, aad, aad_len) != 1 + || EVP_EncryptUpdate(ctx, out, &out_len, in, in_len) != 1 + || EVP_EncryptFinal_ex(ctx, out + out_len, &discard_len) != 1) + { + return 0; + } + + if (in_len != out_len) + return 0; + + return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, out + out_len); +} + +static inline int +EVP_CIPHER_CTX_open_wrapper(EVP_CIPHER_CTX_PTR ctx, + unsigned char *out, + const unsigned char *nonce, + const unsigned char *in, int in_len, + const unsigned char *aad, int aad_len, + const unsigned char *tag) +{ + if (in_len == 0) { + in = (const unsigned char *)""; + // OpenSSL 1.0.2 in FIPS mode contains a bug: it will fail to verify + // unless EVP_DecryptUpdate is called at least once with a non-NULL + // output buffer. OpenSSL will not dereference the output buffer when + // the input length is zero, so set it to an arbitrary non-NULL pointer + // to satisfy OpenSSL when the caller only has authenticated additional + // data (AAD) to verify. While a stack-allocated buffer could be used, + // that would risk a stack-corrupting buffer overflow if OpenSSL + // unexpectedly dereferenced it. Instead pass a value which would + // segfault if dereferenced on any modern platform where a NULL-pointer + // dereference would also segfault. + if (out == NULL) out = (unsigned char *)1; + } + if (aad_len == 0) aad = (const unsigned char *)""; + + if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) + return 0; + + // OpenSSL 1.0.x FIPS Object Module 2.0 versions below 2.0.5 require that + // the tag be set before the ciphertext, otherwise EVP_DecryptUpdate returns + // an error. At least one extant commercially-supported, FIPS validated + // build of OpenSSL 1.0.2 uses FIPS module version 2.0.1. Set the tag first + // to maximize compatibility with all OpenSSL version combinations. + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)(tag)) != 1) + return 0; + + int discard_len, out_len; + if (EVP_DecryptUpdate(ctx, NULL, &discard_len, aad, aad_len) != 1 + || EVP_DecryptUpdate(ctx, out, &out_len, in, in_len) != 1) + { + return 0; + } + + if (EVP_DecryptFinal_ex(ctx, out + out_len, &discard_len) != 1) + return 0; + + if (out_len != in_len) + return 0; + + return 1; +} + +// go_hash_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. +// This is necessary because Go hash.Hash mandates that Sum has no effect +// on the underlying stream. In particular it is OK to Sum, then Write more, +// then Sum again, and the second Sum acts as if the first didn't happen. +// It is written in C because Sum() tend to be in the hot path, +// and doing one cgo call instead of two is a significant performance win. +static inline int +go_hash_sum(EVP_MD_CTX_PTR ctx, EVP_MD_CTX_PTR ctx2, unsigned char *out) +{ + if (EVP_MD_CTX_copy(ctx2, ctx) != 1) + return 0; + // TODO: use EVP_DigestFinal_ex once we know why it leaks + // memory on OpenSSL 1.0.2. + return EVP_DigestFinal(ctx2, out, NULL); +} + +// These wrappers also allocate length variables on the C stack to avoid escape to the heap, but do return the result. +// A struct is returned that contains multiple return values instead of OpenSSL's approach of using pointers. + +typedef struct +{ + int result; + size_t keylen; +} EVP_PKEY_derive_wrapper_out; + +static inline EVP_PKEY_derive_wrapper_out +EVP_PKEY_derive_wrapper(EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t keylen) +{ + EVP_PKEY_derive_wrapper_out r = {0, keylen}; + r.result = EVP_PKEY_derive(ctx, key, &r.keylen); + return r; +} + +typedef struct +{ + int result; + size_t len; +} EVP_PKEY_get_raw_key_out; + +static inline EVP_PKEY_get_raw_key_out +EVP_PKEY_get_raw_public_key_wrapper(const EVP_PKEY_PTR pkey, unsigned char *pub, size_t len) +{ + EVP_PKEY_get_raw_key_out r = {0, len}; + r.result = EVP_PKEY_get_raw_public_key(pkey, pub, &r.len); + return r; +} + +static inline EVP_PKEY_get_raw_key_out +EVP_PKEY_get_raw_private_key_wrapper(const EVP_PKEY_PTR pkey, unsigned char *priv, size_t len) +{ + EVP_PKEY_get_raw_key_out r = {0, len}; + r.result = EVP_PKEY_get_raw_private_key(pkey, priv, &r.len); + return r; +} + +typedef struct +{ + int result; + size_t siglen; +} EVP_DigestSign_wrapper_out; + +static inline EVP_DigestSign_wrapper_out +EVP_DigestSign_wrapper(EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen) +{ + EVP_DigestSign_wrapper_out r = {0, siglen}; + r.result = EVP_DigestSign(ctx, sigret, &r.siglen, tbs, tbslen); + return r; +} From 13e70e52136d0759212899c326462c37b3ee0a8d Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 12:08:27 +0100 Subject: [PATCH 06/20] use ossl instead of direct cgo calls --- aes.go | 4 +- cipher.go | 113 +++++++------- des.go | 4 +- dsa.go | 197 ++++++++++++------------ ec.go | 41 +++-- ecdh.go | 212 +++++++++++++------------ ecdsa.go | 136 +++++++++------- ecdsa_test.go | 1 - ed25519.go | 100 ++++++------ evp.go | 363 ++++++++++++++++++------------------------- export_test.go | 6 +- goopenssl.c | 248 ------------------------------ goopenssl.h | 262 ------------------------------- hash.go | 108 +++++++------ hkdf.go | 164 ++++++++++---------- hmac.go | 124 +++++++-------- init.go | 32 ++-- leak_check.h | 13 ++ openssl.go | 182 ++++++++++++---------- params.go | 103 ++++--------- pbkdf2.go | 25 ++- rand.go | 13 +- rc4.go | 23 +-- rsa.go | 210 +++++++++++++------------ shims.h | 410 ------------------------------------------------- tls1prf.go | 115 +++++++------- 26 files changed, 1131 insertions(+), 2078 deletions(-) delete mode 100644 goopenssl.c delete mode 100644 goopenssl.h create mode 100644 leak_check.h delete mode 100644 shims.h diff --git a/aes.go b/aes.go index 18bb070a..36ad3d69 100644 --- a/aes.go +++ b/aes.go @@ -1,9 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto/cipher" "errors" diff --git a/cipher.go b/cipher.go index 72f7aebf..6f6b56bc 100644 --- a/cipher.go +++ b/cipher.go @@ -1,10 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" - import ( "crypto/cipher" "encoding/binary" @@ -13,6 +10,8 @@ import ( "strconv" "sync" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) type cipherKind int8 @@ -76,9 +75,9 @@ type cacheCipherKey struct { } // loadCipher returns a cipher object for the given k. -func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) { +func loadCipher(k cipherKind, mode cipherMode) (cipher ossl.EVP_CIPHER_PTR) { if v, ok := cacheCipher.Load(cacheCipherKey{k, mode}); ok { - return v.(C.GO_EVP_CIPHER_PTR) + return v.(ossl.EVP_CIPHER_PTR) } defer func() { if cipher != nil && vMajor == 3 { @@ -86,7 +85,7 @@ func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) { // not created by EVP_CIPHER has negative performance // implications, as cipher operations will have // to fetch it on every call. Better to just fetch it once here. - cipher = C.go_openssl_EVP_CIPHER_fetch(nil, C.go_openssl_EVP_CIPHER_get0_name(cipher), nil) + cipher, _ = ossl.EVP_CIPHER_fetch(nil, ossl.EVP_CIPHER_get0_name(cipher), nil) } cacheCipher.Store(cacheCipherKey{k, mode}, cipher) }() @@ -94,52 +93,52 @@ func loadCipher(k cipherKind, mode cipherMode) (cipher C.GO_EVP_CIPHER_PTR) { case cipherAES128: switch mode { case cipherModeECB: - cipher = C.go_openssl_EVP_aes_128_ecb() + cipher = ossl.EVP_aes_128_ecb() case cipherModeCBC: - cipher = C.go_openssl_EVP_aes_128_cbc() + cipher = ossl.EVP_aes_128_cbc() case cipherModeCTR: - cipher = C.go_openssl_EVP_aes_128_ctr() + cipher = ossl.EVP_aes_128_ctr() case cipherModeGCM: - cipher = C.go_openssl_EVP_aes_128_gcm() + cipher = ossl.EVP_aes_128_gcm() } case cipherAES192: switch mode { case cipherModeECB: - cipher = C.go_openssl_EVP_aes_192_ecb() + cipher = ossl.EVP_aes_192_ecb() case cipherModeCBC: - cipher = C.go_openssl_EVP_aes_192_cbc() + cipher = ossl.EVP_aes_192_cbc() case cipherModeCTR: - cipher = C.go_openssl_EVP_aes_192_ctr() + cipher = ossl.EVP_aes_192_ctr() case cipherModeGCM: - cipher = C.go_openssl_EVP_aes_192_gcm() + cipher = ossl.EVP_aes_192_gcm() } case cipherAES256: switch mode { case cipherModeECB: - cipher = C.go_openssl_EVP_aes_256_ecb() + cipher = ossl.EVP_aes_256_ecb() case cipherModeCBC: - cipher = C.go_openssl_EVP_aes_256_cbc() + cipher = ossl.EVP_aes_256_cbc() case cipherModeCTR: - cipher = C.go_openssl_EVP_aes_256_ctr() + cipher = ossl.EVP_aes_256_ctr() case cipherModeGCM: - cipher = C.go_openssl_EVP_aes_256_gcm() + cipher = ossl.EVP_aes_256_gcm() } case cipherDES: switch mode { case cipherModeECB: - cipher = C.go_openssl_EVP_des_ecb() + cipher = ossl.EVP_des_ecb() case cipherModeCBC: - cipher = C.go_openssl_EVP_des_cbc() + cipher = ossl.EVP_des_cbc() } case cipherDES3: switch mode { case cipherModeECB: - cipher = C.go_openssl_EVP_des_ede3_ecb() + cipher = ossl.EVP_des_ede3_ecb() case cipherModeCBC: - cipher = C.go_openssl_EVP_des_ede3_cbc() + cipher = ossl.EVP_des_ede3_cbc() } case cipherRC4: - cipher = C.go_openssl_EVP_rc4() + cipher = ossl.EVP_rc4() } return cipher } @@ -157,7 +156,7 @@ func newEVPCipher(key []byte, kind cipherKind) (*evpCipher, error) { } c := &evpCipher{key: make([]byte, len(key)), kind: kind} copy(c.key, key) - c.blockSize = int(C.go_openssl_EVP_CIPHER_get_block_size(cipher)) + c.blockSize = int(ossl.EVP_CIPHER_get_block_size(cipher)) return c, nil } @@ -177,9 +176,9 @@ func (c *evpCipher) encrypt(dst, src []byte) error { if err != nil { return err } - defer C.go_openssl_EVP_CIPHER_CTX_free(enc_ctx) + defer ossl.EVP_CIPHER_CTX_free(enc_ctx) - if C.go_openssl_EVP_EncryptUpdate_wrapper(enc_ctx, base(dst), base(src), C.int(c.blockSize)) != 1 { + if ossl.EVP_EncryptUpdate_wrapper(enc_ctx, unsafe.SliceData(dst), unsafe.SliceData(src), int32(c.blockSize)) != nil { return errors.New("EncryptUpdate failed") } runtime.KeepAlive(c) @@ -202,24 +201,24 @@ func (c *evpCipher) decrypt(dst, src []byte) error { if err != nil { return err } - defer C.go_openssl_EVP_CIPHER_CTX_free(dec_ctx) + defer ossl.EVP_CIPHER_CTX_free(dec_ctx) - if C.go_openssl_EVP_CIPHER_CTX_set_padding(dec_ctx, 0) != 1 { + if ossl.EVP_CIPHER_CTX_set_padding(dec_ctx, 0) != nil { return errors.New("could not disable cipher padding") } - C.go_openssl_EVP_DecryptUpdate_wrapper(dec_ctx, base(dst), base(src), C.int(c.blockSize)) + ossl.EVP_DecryptUpdate_wrapper(dec_ctx, unsafe.SliceData(dst), unsafe.SliceData(src), int32(c.blockSize)) runtime.KeepAlive(c) return nil } type cipherCBC struct { - ctx C.GO_EVP_CIPHER_CTX_PTR + ctx ossl.EVP_CIPHER_CTX_PTR blockSize int } func (c *cipherCBC) finalize() { - C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) + ossl.EVP_CIPHER_CTX_free(c.ctx) } func (x *cipherCBC) BlockSize() int { return x.blockSize } @@ -235,7 +234,7 @@ func (x *cipherCBC) CryptBlocks(dst, src []byte) { panic("crypto/cipher: output smaller than input") } if len(src) > 0 { - if C.go_openssl_EVP_CipherUpdate_wrapper(x.ctx, base(dst), base(src), C.int(len(src))) != 1 { + if ossl.EVP_CipherUpdate_wrapper(x.ctx, unsafe.SliceData(dst), unsafe.SliceData(src), int32(len(src))) != nil { panic("crypto/cipher: CipherUpdate failed") } runtime.KeepAlive(x) @@ -246,7 +245,7 @@ func (x *cipherCBC) SetIV(iv []byte) { if len(iv) != x.blockSize { panic("cipher: incorrect length IV") } - if C.go_openssl_EVP_CipherInit_ex(x.ctx, nil, nil, nil, base(iv), C.int(cipherOpNone)) != 1 { + if ossl.EVP_CipherInit_ex(x.ctx, nil, nil, nil, unsafe.SliceData(iv), int32(cipherOpNone)) != nil { panic("cipher: unable to initialize EVP cipher ctx") } } @@ -258,14 +257,14 @@ func (c *evpCipher) newCBC(iv []byte, op cipherOp) cipher.BlockMode { } x := &cipherCBC{ctx: ctx, blockSize: c.blockSize} runtime.SetFinalizer(x, (*cipherCBC).finalize) - if C.go_openssl_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { + if ossl.EVP_CIPHER_CTX_set_padding(x.ctx, 0) != nil { panic("cipher: unable to set padding") } return x } type cipherCTR struct { - ctx C.GO_EVP_CIPHER_CTX_PTR + ctx ossl.EVP_CIPHER_CTX_PTR } func (x *cipherCTR) XORKeyStream(dst, src []byte) { @@ -278,7 +277,7 @@ func (x *cipherCTR) XORKeyStream(dst, src []byte) { if len(src) == 0 { return } - if C.go_openssl_EVP_EncryptUpdate_wrapper(x.ctx, base(dst), base(src), C.int(len(src))) != 1 { + if ossl.EVP_EncryptUpdate_wrapper(x.ctx, base(dst), base(src), int32(len(src))) != nil { panic("crypto/cipher: EncryptUpdate failed") } runtime.KeepAlive(x) @@ -295,7 +294,7 @@ func (c *evpCipher) newCTR(iv []byte) cipher.Stream { } func (c *cipherCTR) finalize() { - C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) + ossl.EVP_CIPHER_CTX_free(c.ctx) } type cipherGCMTLS uint8 @@ -445,7 +444,7 @@ func (g *cipherGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { if err != nil { panic(err) } - defer C.go_openssl_EVP_CIPHER_CTX_free(ctx) + defer ossl.EVP_CIPHER_CTX_free(ctx) // Encrypt additional data. // When sealing a TLS payload, OpenSSL app sets the additional data using // 'EVP_CIPHER_CTX_ctrl(g.ctx, C.EVP_CTRL_AEAD_TLS1_AAD, C.EVP_AEAD_TLS1_AAD_LEN, base(additionalData))'. @@ -453,9 +452,9 @@ func (g *cipherGCM) Seal(dst, nonce, plaintext, additionalData []byte) []byte { // relying in the explicit nonce being securely set externally, // and it also gives some interesting speed gains. // Unfortunately we can't use it because Go expects AEAD.Seal to honor the provided nonce. - if C.go_openssl_EVP_CIPHER_CTX_seal_wrapper(ctx, base(out), base(nonce), - base(plaintext), C.int(len(plaintext)), - base(additionalData), C.int(len(additionalData))) != 1 { + if ossl.EVP_CIPHER_CTX_seal_wrapper(ctx, base(out), base(nonce), + base(plaintext), int32(len(plaintext)), + base(additionalData), int32(len(additionalData))) != nil { panic(fail("EVP_CIPHER_CTX_seal")) } @@ -492,13 +491,13 @@ func (g *cipherGCM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, if err != nil { return nil, err } - defer C.go_openssl_EVP_CIPHER_CTX_free(ctx) - ok := C.go_openssl_EVP_CIPHER_CTX_open_wrapper( + defer ossl.EVP_CIPHER_CTX_free(ctx) + err = ossl.EVP_CIPHER_CTX_open_wrapper( ctx, base(out), base(nonce), - base(ciphertext), C.int(len(ciphertext)), - base(additionalData), C.int(len(additionalData)), base(tag)) + base(ciphertext), int32(len(ciphertext)), + base(additionalData), int32(len(additionalData)), base(tag)) runtime.KeepAlive(g) - if ok == 0 { + if err != nil { // Zero output buffer on error. for i := range out { out[i] = 0 @@ -520,35 +519,35 @@ func sliceForAppend(in []byte, n int) (head, tail []byte) { return } -func newCipherCtx(kind cipherKind, mode cipherMode, encrypt cipherOp, key, iv []byte) (_ C.GO_EVP_CIPHER_CTX_PTR, err error) { +func newCipherCtx(kind cipherKind, mode cipherMode, encrypt cipherOp, key, iv []byte) (_ ossl.EVP_CIPHER_CTX_PTR, err error) { cipher := loadCipher(kind, mode) if cipher == nil { panic("crypto/cipher: unsupported cipher: " + kind.String()) } - ctx := C.go_openssl_EVP_CIPHER_CTX_new() - if ctx == nil { + ctx, err := ossl.EVP_CIPHER_CTX_new() + if err != nil { return nil, fail("unable to create EVP cipher ctx") } defer func() { if err != nil { - C.go_openssl_EVP_CIPHER_CTX_free(ctx) + ossl.EVP_CIPHER_CTX_free(ctx) } }() if kind == cipherRC4 { // RC4 cipher supports a variable key length. // We need to set the key length before setting the key, // and to do so we need to have an initialized cipher ctx. - if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, nil, nil, C.int(encrypt)) != 1 { - return nil, newOpenSSLError("EVP_CipherInit_ex") + if err := ossl.EVP_CipherInit_ex(ctx, cipher, nil, nil, nil, int32(encrypt)); err != nil { + return nil, err } - if C.go_openssl_EVP_CIPHER_CTX_set_key_length(ctx, C.int(len(key))) != 1 { - return nil, newOpenSSLError("EVP_CIPHER_CTX_set_key_length") + if err := ossl.EVP_CIPHER_CTX_set_key_length(ctx, int32(len(key))); err != nil { + return nil, err } // Pass nil to the next call to EVP_CipherInit_ex to avoid resetting ctx's cipher. cipher = nil } - if C.go_openssl_EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), C.int(encrypt)) != 1 { - return nil, newOpenSSLError("unable to initialize EVP cipher ctx") + if err := ossl.EVP_CipherInit_ex(ctx, cipher, nil, base(key), base(iv), int32(encrypt)); err != nil { + return nil, err } return ctx, nil } diff --git a/des.go b/des.go index cd006544..6a475137 100644 --- a/des.go +++ b/des.go @@ -1,9 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto/cipher" "errors" diff --git a/dsa.go b/dsa.go index c56071f5..73a2cd76 100644 --- a/dsa.go +++ b/dsa.go @@ -1,21 +1,21 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "runtime" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) // 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) - if ctx == nil { + ctx, err := ossl.EVP_PKEY_CTX_new_id(ossl.EVP_PKEY_DSA, nil) + if err != nil { return false } - C.go_openssl_EVP_PKEY_CTX_free(ctx) + ossl.EVP_PKEY_CTX_free(ctx) return true } @@ -30,14 +30,14 @@ type PrivateKeyDSA struct { X, Y BigInt // _pkey MUST NOT be accessed directly. Instead, use the withKey method. - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func (k *PrivateKeyDSA) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } -func (k *PrivateKeyDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { +func (k *PrivateKeyDSA) withKey(f func(ossl.EVP_PKEY_PTR) error) error { defer runtime.KeepAlive(k) return f(k._pkey) } @@ -48,14 +48,14 @@ type PublicKeyDSA struct { Y BigInt // _pkey MUST NOT be accessed directly. Instead, use the withKey method. - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func (k *PublicKeyDSA) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } -func (k *PublicKeyDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { +func (k *PublicKeyDSA) withKey(f func(ossl.EVP_PKEY_PTR) error) error { defer runtime.KeepAlive(k) return f(k._pkey) } @@ -66,46 +66,50 @@ func GenerateDSAParameters(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) - if ctx == nil { - return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_new_id failed") + ctx, err := ossl.EVP_PKEY_CTX_new_id(ossl.EVP_PKEY_DSA, nil) + if err != nil { + return DSAParameters{}, err } - 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") + defer ossl.EVP_PKEY_CTX_free(ctx) + if err := ossl.EVP_PKEY_paramgen_init(ctx); err != nil { + return DSAParameters{}, err } - 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 { - return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_DSA, -1, ossl.EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, int32(l), nil); err != nil { + return DSAParameters{}, err } - 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 { - return DSAParameters{}, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_DSA, -1, ossl.EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, int32(n), nil); err != nil { + return DSAParameters{}, err } - var pkey C.GO_EVP_PKEY_PTR - if C.go_openssl_EVP_PKEY_paramgen(ctx, &pkey) != 1 { - return DSAParameters{}, newOpenSSLError("EVP_PKEY_paramgen failed") + var pkey ossl.EVP_PKEY_PTR + if err := ossl.EVP_PKEY_paramgen(ctx, &pkey); err != nil { + return DSAParameters{}, err } - defer C.go_openssl_EVP_PKEY_free(pkey) + defer ossl.EVP_PKEY_free(pkey) // Extract the domain parameters from the generated key. - var p, q, g C.GO_BIGNUM_PTR + var p, q, g ossl.BIGNUM_PTR switch vMajor { case 1: dsa := getDSA(pkey) if vMinor == 0 { - C.go_openssl_DSA_get0_pqg_backport(dsa, &p, &q, &g) + ossl.DSA_get0_pqg_backport(dsa, &p, &q, &g) } else { - C.go_openssl_DSA_get0_pqg(dsa, &p, &q, &g) + ossl.DSA_get0_pqg(dsa, &p, &q, &g) } case 3: defer func() { - C.go_openssl_BN_free(p) - C.go_openssl_BN_free(q) - C.go_openssl_BN_free(g) + ossl.BN_free(p) + ossl.BN_free(q) + ossl.BN_free(g) }() - if C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_FFC_P, &p) != 1 || - C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_FFC_Q, &q) != 1 || - C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_FFC_G, &g) != 1 { - return DSAParameters{}, newOpenSSLError("EVP_PKEY_get_bn_param") + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_P, &p); err != err { + return DSAParameters{}, err + } + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_Q, &q); err != err { + return DSAParameters{}, err + } + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_G, &g); err != err { + return DSAParameters{}, err } default: panic(errUnsupportedVersion()) @@ -152,23 +156,25 @@ func GenerateKeyDSA(params DSAParameters) (*PrivateKeyDSA, error) { if err != nil { return nil, err } - var x, y C.GO_BIGNUM_PTR + var x, y ossl.BIGNUM_PTR switch vMajor { case 1: dsa := getDSA(pkey) if vMinor == 0 { - C.go_openssl_DSA_get0_key_backport(dsa, &y, &x) + ossl.DSA_get0_key_backport(dsa, &y, &x) } else { - C.go_openssl_DSA_get0_key(dsa, &y, &x) + ossl.DSA_get0_key(dsa, &y, &x) } case 3: defer func() { - C.go_openssl_BN_clear_free(x) - C.go_openssl_BN_free(y) + ossl.BN_clear_free(x) + ossl.BN_free(y) }() - if C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PUB_KEY, &y) != 1 || - C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PRIV_KEY, &x) != 1 { - return nil, newOpenSSLError("EVP_PKEY_get_bn_param") + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_PUB_KEY, &y); err != nil { + return nil, err + } + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_PRIV_KEY, &x); err != nil { + return nil, err } default: panic(errUnsupportedVersion()) @@ -188,7 +194,7 @@ func VerifyDSA(pub *PublicKeyDSA, hash []byte, sig []byte) bool { return evpVerify(pub.withKey, 0, 0, 0, sig, hash) == nil } -func newDSA(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { +func newDSA(params DSAParameters, x, y BigInt) (ossl.EVP_PKEY_PTR, error) { switch vMajor { case 1: return newDSA1(params, x, y) @@ -199,61 +205,60 @@ func newDSA(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { } } -func newDSA1(params DSAParameters, x, y BigInt) (pkey C.GO_EVP_PKEY_PTR, err error) { +func newDSA1(params DSAParameters, x, y BigInt) (pkey ossl.EVP_PKEY_PTR, _ error) { checkMajorVersion(1) - dsa := C.go_openssl_DSA_new() - if dsa == nil { - return nil, newOpenSSLError("DSA_new failed") + dsa, err := ossl.DSA_new() + if err != nil { + return nil, err } defer func() { if pkey == nil { - C.go_openssl_DSA_free(dsa) + ossl.DSA_free(dsa) } }() p, q, g := bigToBN(params.P), bigToBN(params.Q), bigToBN(params.G) - var ret C.int if vMinor == 0 { - ret = C.go_openssl_DSA_set0_pqg_backport(dsa, p, q, g) + err = ossl.DSA_set0_pqg_backport(dsa, p, q, g) } else { - ret = C.go_openssl_DSA_set0_pqg(dsa, p, q, g) + err = ossl.DSA_set0_pqg(dsa, p, q, g) } - if ret != 1 { - C.go_openssl_BN_free(p) - C.go_openssl_BN_free(q) - C.go_openssl_BN_free(g) - return nil, newOpenSSLError("DSA_set0_pqg failed") + if err != nil { + ossl.BN_free(p) + ossl.BN_free(q) + ossl.BN_free(g) + return nil, err } if y != nil { pub, priv := bigToBN(y), bigToBN(x) if vMinor == 0 { - ret = C.go_openssl_DSA_set0_key_backport(dsa, pub, priv) + err = ossl.DSA_set0_key_backport(dsa, pub, priv) } else { - ret = C.go_openssl_DSA_set0_key(dsa, pub, priv) + err = ossl.DSA_set0_key(dsa, pub, priv) } - if ret != 1 { - C.go_openssl_BN_free(pub) - C.go_openssl_BN_clear_free(priv) - return nil, newOpenSSLError("DSA_set0_key failed") + if err != nil { + ossl.BN_free(pub) + ossl.BN_clear_free(priv) + return nil, err } } else { - if C.go_openssl_DSA_generate_key(dsa) != 1 { - return nil, newOpenSSLError("DSA_generate_key failed") + if err := ossl.DSA_generate_key(dsa); err != nil { + return nil, err } } - pkey = C.go_openssl_EVP_PKEY_new() - if pkey == nil { - return nil, newOpenSSLError("EVP_PKEY_new failed") + pkey, err = ossl.EVP_PKEY_new() + if err != nil { + return nil, err } - if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_DSA, unsafe.Pointer(dsa)) != 1 { - C.go_openssl_EVP_PKEY_free(pkey) - return nil, newOpenSSLError("EVP_PKEY_assign failed") + if err := ossl.EVP_PKEY_assign(pkey, ossl.EVP_PKEY_DSA, unsafe.Pointer(dsa)); err != nil { + ossl.EVP_PKEY_free(pkey) + return nil, err } return pkey, nil } -func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { +func newDSA3(params DSAParameters, x, y BigInt) (ossl.EVP_PKEY_PTR, error) { checkMajorVersion(3) bld, err := newParamBuilder() @@ -262,25 +267,25 @@ func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { } defer bld.finalize() - 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) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_FFC_P, params.P, false) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_FFC_Q, params.Q, false) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_FFC_G, params.G, false) + selection := ossl.EVP_PKEY_KEYPAIR if y != nil { - bld.addBigInt(_OSSL_PKEY_PARAM_PUB_KEY, y, false) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_PUB_KEY, y, false) if x == nil { - selection = C.int(C.GO_EVP_PKEY_PUBLIC_KEY) + selection = ossl.EVP_PKEY_PUBLIC_KEY } } if x != nil { - bld.addBigInt(_OSSL_PKEY_PARAM_PRIV_KEY, x, true) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_PRIV_KEY, x, true) } bldparams, err := bld.build() if err != nil { return nil, err } - defer C.go_openssl_OSSL_PARAM_free(bldparams) - pkey, err := newEvpFromParams(C.GO_EVP_PKEY_DSA, selection, bldparams) + defer ossl.OSSL_PARAM_free(bldparams) + pkey, err := newEvpFromParams(ossl.EVP_PKEY_DSA, selection, bldparams) if err != nil { return nil, err } @@ -290,18 +295,18 @@ func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { // pkey doesn't contain the public component, but the crypto/dsa package // expects it to be always there. Generate a new key using pkey as domain // parameters placeholder. - defer C.go_openssl_EVP_PKEY_free(pkey) - ctx := C.go_openssl_EVP_PKEY_CTX_new_from_pkey(nil, pkey, nil) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new_from_pkey") + defer ossl.EVP_PKEY_free(pkey) + ctx, err := ossl.EVP_PKEY_CTX_new_from_pkey(nil, pkey, nil) + if err != nil { + return nil, err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { - return nil, newOpenSSLError("EVP_PKEY_keygen_init") + defer ossl.EVP_PKEY_CTX_free(ctx) + if err := ossl.EVP_PKEY_keygen_init(ctx); err != nil { + return nil, err } - var gkey C.GO_EVP_PKEY_PTR - if C.go_openssl_EVP_PKEY_keygen(ctx, &gkey) != 1 { - return nil, newOpenSSLError("EVP_PKEY_keygen") + var gkey ossl.EVP_PKEY_PTR + if err := ossl.EVP_PKEY_keygen(ctx, &gkey); err != nil { + return nil, err } return gkey, nil } @@ -309,13 +314,13 @@ func newDSA3(params DSAParameters, x, y BigInt) (C.GO_EVP_PKEY_PTR, error) { // getDSA returns the DSA from pkey. // If pkey does not contain an DSA it panics. // The returned key should not be freed. -func getDSA(pkey C.GO_EVP_PKEY_PTR) (key C.GO_DSA_PTR) { +func getDSA(pkey ossl.EVP_PKEY_PTR) (key ossl.DSA_PTR) { if vMajor == 1 && vMinor == 0 { - if key0 := C.go_openssl_EVP_PKEY_get0(pkey); key0 != nil { - key = C.GO_DSA_PTR(key0) + if key0, err := ossl.EVP_PKEY_get0(pkey); err == nil { + key = ossl.DSA_PTR(key0) } } else { - key = C.go_openssl_EVP_PKEY_get0_DSA(pkey) + key, _ = ossl.EVP_PKEY_get0_DSA(pkey) } if key == nil { panic("pkey does not contain an DSA") diff --git a/ec.go b/ec.go index 03c51e5a..e27bec68 100644 --- a/ec.go +++ b/ec.go @@ -1,51 +1,50 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" +import "github.com/golang-fips/openssl/v2/internal/ossl" -func curveNID(curve string) (C.int, error) { +func curveNID(curve string) (int, error) { switch curve { case "P-224": - return C.GO_NID_secp224r1, nil + return ossl.NID_secp224r1, nil case "P-256": - return C.GO_NID_X9_62_prime256v1, nil + return ossl.NID_X9_62_prime256v1, nil case "P-384": - return C.GO_NID_secp384r1, nil + return ossl.NID_secp384r1, nil case "P-521": - return C.GO_NID_secp521r1, nil + return ossl.NID_secp521r1, nil } return 0, errUnknownCurve } // encodeEcPoint encodes pt. -func encodeEcPoint(group C.GO_EC_GROUP_PTR, pt C.GO_EC_POINT_PTR) ([]byte, error) { +func encodeEcPoint(group ossl.EC_GROUP_PTR, pt ossl.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) - if n == 0 { - return nil, newOpenSSLError("EC_POINT_point2oct") + n, err := ossl.EC_POINT_point2oct(group, pt, ossl.POINT_CONVERSION_UNCOMPRESSED, nil, 0, nil) + if err != nil { + return nil, err } // 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) - if n == 0 { - return nil, newOpenSSLError("EC_POINT_point2oct") + n, err = ossl.EC_POINT_point2oct(group, pt, ossl.POINT_CONVERSION_UNCOMPRESSED, base(bytes), n, nil) + if err != nil { + return nil, err } return bytes, nil } // generateAndEncodeEcPublicKey calls newPubKeyPointFn to generate a public key point and then encodes it. -func generateAndEncodeEcPublicKey(nid C.int, newPubKeyPointFn func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error)) ([]byte, error) { - group := C.go_openssl_EC_GROUP_new_by_curve_name(nid) - if group == nil { - return nil, newOpenSSLError("EC_GROUP_new_by_curve_name") +func generateAndEncodeEcPublicKey(nid int, newPubKeyPointFn func(group ossl.EC_GROUP_PTR) (ossl.EC_POINT_PTR, error)) ([]byte, error) { + group, err := ossl.EC_GROUP_new_by_curve_name(int32(nid)) + if err != nil { + return nil, err } - defer C.go_openssl_EC_GROUP_free(group) + defer ossl.EC_GROUP_free(group) pt, err := newPubKeyPointFn(group) if err != nil { return nil, err } - defer C.go_openssl_EC_POINT_free(pt) + defer ossl.EC_POINT_free(pt) return encodeEcPoint(group, pt) } diff --git a/ecdh.go b/ecdh.go index 5b146749..d748771c 100644 --- a/ecdh.go +++ b/ecdh.go @@ -1,32 +1,32 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "errors" "runtime" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) type PublicKeyECDH struct { - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR bytes []byte } func (k *PublicKeyECDH) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } type PrivateKeyECDH struct { - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR curve string hasPublicKey bool } func (k *PrivateKeyECDH) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) { @@ -63,44 +63,48 @@ func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { } k.hasPublicKey = true } - var pkey C.GO_EVP_PKEY_PTR + var pkey ossl.EVP_PKEY_PTR defer func() { - C.go_openssl_EVP_PKEY_free(pkey) + ossl.EVP_PKEY_free(pkey) }() var bytes []byte switch vMajor { case 1: - pkey = C.go_openssl_EVP_PKEY_new() - if pkey == nil { - return nil, newOpenSSLError("EVP_PKEY_new") + var err error + pkey, err = ossl.EVP_PKEY_new() + if err != nil { + return nil, err } key := getECKey(k._pkey) - if C.go_openssl_EVP_PKEY_set1_EC_KEY(pkey, key) != 1 { - return nil, newOpenSSLError("EVP_PKEY_set1_EC_KEY") + if err := ossl.EVP_PKEY_set1_EC_KEY(pkey, key); err != nil { + return nil, err } - pt := C.go_openssl_EC_KEY_get0_public_key(key) - if pt == nil { - return nil, newOpenSSLError("EC_KEY_get0_public_key") + pt, err := ossl.EC_KEY_get0_public_key(key) + if err != nil { + return nil, err + } + group, err := ossl.EC_KEY_get0_group(key) + if err != nil { + return nil, err } - group := C.go_openssl_EC_KEY_get0_group(key) - var err error bytes, err = encodeEcPoint(group, pt) if err != nil { return nil, err } case 3: pkey = k._pkey - if C.go_openssl_EVP_PKEY_up_ref(pkey) != 1 { - return nil, newOpenSSLError("EVP_PKEY_up_ref") + if err := ossl.EVP_PKEY_up_ref(pkey); err != nil { + return nil, err } - var cbytes *C.uchar - n := C.go_openssl_EVP_PKEY_get1_encoded_public_key(k._pkey, &cbytes) - if n == 0 { - return nil, newOpenSSLError("EVP_PKEY_get_octet_string_param") + var cbytes *byte + n, err := ossl.EVP_PKEY_get1_encoded_public_key(k._pkey, &cbytes) + if err != nil { + return nil, err } - bytes = C.GoBytes(unsafe.Pointer(cbytes), C.int(n)) + bytes = make([]byte, n) + copy(bytes, unsafe.Slice(cbytes, n)) cryptoFree(unsafe.Pointer(cbytes)) default: panic(errUnsupportedVersion()) @@ -111,7 +115,7 @@ func (k *PrivateKeyECDH) PublicKey() (*PublicKeyECDH, error) { return pub, nil } -func newECDHPkey(curve string, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, error) { +func newECDHPkey(curve string, bytes []byte, isPrivate bool) (ossl.EVP_PKEY_PTR, error) { nid, err := curveNID(curve) if err != nil { return nil, err @@ -126,45 +130,48 @@ func newECDHPkey(curve string, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, } } -func newECDHPkey1(nid C.int, bytes []byte, isPrivate bool) (pkey C.GO_EVP_PKEY_PTR, err error) { +func newECDHPkey1(nid int, bytes []byte, isPrivate bool) (pkey ossl.EVP_PKEY_PTR, err error) { checkMajorVersion(1) - key := C.go_openssl_EC_KEY_new_by_curve_name(nid) - if key == nil { - return nil, newOpenSSLError("EC_KEY_new_by_curve_name") + key, err := ossl.EC_KEY_new_by_curve_name(int32(nid)) + if err != nil { + return nil, err } defer func() { if pkey == nil { - C.go_openssl_EC_KEY_free(key) + ossl.EC_KEY_free(key) } }() if isPrivate { - priv := C.go_openssl_BN_bin2bn(base(bytes), C.int(len(bytes)), nil) - if priv == nil { - return nil, newOpenSSLError("BN_bin2bn") + priv, err := ossl.BN_bin2bn(base(bytes), int32(len(bytes)), nil) + if err != nil { + return nil, err } - defer C.go_openssl_BN_clear_free(priv) - if C.go_openssl_EC_KEY_set_private_key(key, priv) != 1 { - return nil, newOpenSSLError("EC_KEY_set_private_key") + defer ossl.BN_clear_free(priv) + if err := ossl.EC_KEY_set_private_key(key, priv); err != nil { + return nil, err } } else { - group := C.go_openssl_EC_KEY_get0_group(key) - pub := C.go_openssl_EC_POINT_new(group) - if pub == nil { - return nil, newOpenSSLError("EC_POINT_new") + group, err := ossl.EC_KEY_get0_group(key) + if err != nil { + return nil, err } - defer C.go_openssl_EC_POINT_free(pub) - if C.go_openssl_EC_POINT_oct2point(group, pub, base(bytes), C.size_t(len(bytes)), nil) != 1 { + pub, err := ossl.EC_POINT_new(group) + if err != nil { + return nil, err + } + defer ossl.EC_POINT_free(pub) + if ossl.EC_POINT_oct2point(group, pub, base(bytes), len(bytes), nil) != nil { return nil, errors.New("point not on curve") } - if C.go_openssl_EC_KEY_set_public_key(key, pub) != 1 { - return nil, newOpenSSLError("EC_KEY_set_public_key") + if err := ossl.EC_KEY_set_public_key(key, pub); err != nil { + return nil, err } } return newEVPPKEY(key) } -func newECDHPkey3(nid C.int, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, error) { +func newECDHPkey3(nid int, bytes []byte, isPrivate bool) (ossl.EVP_PKEY_PTR, error) { checkMajorVersion(3) bld, err := newParamBuilder() @@ -172,72 +179,75 @@ func newECDHPkey3(nid C.int, bytes []byte, isPrivate bool) (C.GO_EVP_PKEY_PTR, e return nil, err } defer bld.finalize() - bld.addUTF8String(_OSSL_PKEY_PARAM_GROUP_NAME, C.go_openssl_OBJ_nid2sn(nid), 0) - var selection C.int + bld.addUTF8String(ossl.OSSL_PKEY_PARAM_GROUP_NAME, ossl.OBJ_nid2sn(int32(nid)), 0) + var selection int if isPrivate { - bld.addBin(_OSSL_PKEY_PARAM_PRIV_KEY, bytes, true) - selection = C.GO_EVP_PKEY_KEYPAIR + bld.addBin(ossl.OSSL_PKEY_PARAM_PRIV_KEY, bytes, true) + selection = ossl.EVP_PKEY_KEYPAIR } else { - bld.addOctetString(_OSSL_PKEY_PARAM_PUB_KEY, bytes) - selection = C.GO_EVP_PKEY_PUBLIC_KEY + bld.addOctetString(ossl.OSSL_PKEY_PARAM_PUB_KEY, bytes) + selection = ossl.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) + defer ossl.OSSL_PARAM_free(params) + return newEvpFromParams(ossl.EVP_PKEY_EC, selection, params) } // deriveEcdhPublicKey sets the raw public key of pkey by deriving it from // the raw private key. -func deriveEcdhPublicKey(pkey C.GO_EVP_PKEY_PTR, curve string) error { - derive := func(group C.GO_EC_GROUP_PTR, priv C.GO_BIGNUM_PTR) (C.GO_EC_POINT_PTR, error) { +func deriveEcdhPublicKey(pkey ossl.EVP_PKEY_PTR, curve string) error { + derive := func(group ossl.EC_GROUP_PTR, priv ossl.BIGNUM_PTR) (ossl.EC_POINT_PTR, error) { // OpenSSL does not expose any method to generate the public // key from the private key [1], so we have to calculate it here. // [1] https://github.com/openssl/openssl/issues/18437#issuecomment-1144717206 - pt := C.go_openssl_EC_POINT_new(group) - if pt == nil { - return nil, newOpenSSLError("EC_POINT_new") + pt, err := ossl.EC_POINT_new(group) + if err != nil { + return nil, err } - if C.go_openssl_EC_POINT_mul(group, pt, priv, nil, nil, nil) == 0 { - C.go_openssl_EC_POINT_free(pt) - return nil, newOpenSSLError("EC_POINT_mul") + if err := ossl.EC_POINT_mul(group, pt, priv, nil, nil, nil); err != nil { + ossl.EC_POINT_free(pt) + return nil, err } return pt, nil } switch vMajor { case 1: key := getECKey(pkey) - priv := C.go_openssl_EC_KEY_get0_private_key(key) - if priv == nil { - return newOpenSSLError("EC_KEY_get0_private_key") + priv, err := ossl.EC_KEY_get0_private_key(key) + if err != nil { + return err + } + group, err := ossl.EC_KEY_get0_group(key) + if err != nil { + return err } - group := C.go_openssl_EC_KEY_get0_group(key) pub, err := derive(group, priv) if err != nil { return err } - defer C.go_openssl_EC_POINT_free(pub) - if C.go_openssl_EC_KEY_set_public_key(key, pub) != 1 { - return newOpenSSLError("EC_KEY_set_public_key") + defer ossl.EC_POINT_free(pub) + if err := ossl.EC_KEY_set_public_key(key, pub); err != nil { + return err } case 3: - var priv C.GO_BIGNUM_PTR - if C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PRIV_KEY, &priv) != 1 { - return newOpenSSLError("EVP_PKEY_get_bn_param") + var priv ossl.BIGNUM_PTR + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_PRIV_KEY, &priv); err != nil { + return err } - defer C.go_openssl_BN_clear_free(priv) + defer ossl.BN_clear_free(priv) nid, _ := curveNID(curve) - pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error) { + pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group ossl.EC_GROUP_PTR) (ossl.EC_POINT_PTR, error) { return derive(group, priv) }) if err != nil { return err } - if C.go_openssl_EVP_PKEY_set1_encoded_public_key(pkey, base(pubBytes), C.size_t(len(pubBytes))) != 1 { - return newOpenSSLError("EVP_PKEY_set1_encoded_public_key") + if err := ossl.EVP_PKEY_set1_encoded_public_key(pkey, base(pubBytes), len(pubBytes)); err != nil { + return err } default: panic(errUnsupportedVersion()) @@ -248,52 +258,52 @@ func deriveEcdhPublicKey(pkey C.GO_EVP_PKEY_PTR, curve string) error { func ECDH(priv *PrivateKeyECDH, pub *PublicKeyECDH) ([]byte, error) { defer runtime.KeepAlive(priv) defer runtime.KeepAlive(pub) - ctx := C.go_openssl_EVP_PKEY_CTX_new(priv._pkey, nil) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new") + ctx, err := ossl.EVP_PKEY_CTX_new(priv._pkey, nil) + if err != nil { + return nil, err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive_init") + defer ossl.EVP_PKEY_CTX_free(ctx) + if err := ossl.EVP_PKEY_derive_init(ctx); err != nil { + return nil, err } - if C.go_openssl_EVP_PKEY_derive_set_peer(ctx, pub._pkey) != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive_set_peer") + if err := ossl.EVP_PKEY_derive_set_peer(ctx, pub._pkey); err != nil { + return nil, err } - r := C.go_openssl_EVP_PKEY_derive_wrapper(ctx, nil, 0) - if r.result != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive_init") + keyLength, err := ossl.EVP_PKEY_derive_wrapper(ctx, nil, 0) + if err != nil { + return nil, err } - out := make([]byte, r.keylen) - if C.go_openssl_EVP_PKEY_derive_wrapper(ctx, base(out), r.keylen).result != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive_init") + out := make([]byte, keyLength) + if _, err := ossl.EVP_PKEY_derive_wrapper(ctx, base(out), keyLength); err != nil { + return nil, err } return out, nil } func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { - pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) + pkey, err := generateEVPPKey(ossl.EVP_PKEY_EC, 0, curve) if err != nil { return nil, nil, err } var k *PrivateKeyECDH defer func() { if k == nil { - C.go_openssl_EVP_PKEY_free(pkey) + ossl.EVP_PKEY_free(pkey) } }() - var priv C.GO_BIGNUM_PTR + var priv ossl.BIGNUM_PTR switch vMajor { case 1: key := getECKey(pkey) - priv = C.go_openssl_EC_KEY_get0_private_key(key) - if priv == nil { - return nil, nil, newOpenSSLError("EC_KEY_get0_private_key") + priv, err = ossl.EC_KEY_get0_private_key(key) + if err != nil { + return nil, nil, err } case 3: - if C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PRIV_KEY, &priv) != 1 { - return nil, nil, newOpenSSLError("EVP_PKEY_get_bn_param") + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_PRIV_KEY, &priv); err != nil { + return nil, nil, err } - defer C.go_openssl_BN_clear_free(priv) + defer ossl.BN_clear_free(priv) default: panic(errUnsupportedVersion()) } @@ -302,7 +312,7 @@ func GenerateKeyECDH(curve string) (*PrivateKeyECDH, []byte, error) { // 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 := C.go_openssl_EVP_PKEY_get_bits(pkey) + bits := ossl.EVP_PKEY_get_bits(pkey) bytes := make([]byte, (bits+7)/8) if err := bnToBinPad(priv, bytes); err != nil { return nil, nil, err diff --git a/ecdsa.go b/ecdsa.go index f85782a6..d7de63cd 100644 --- a/ecdsa.go +++ b/ecdsa.go @@ -1,39 +1,39 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto" "errors" "runtime" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) type PrivateKeyECDSA struct { // _pkey MUST NOT be accessed directly. Instead, use the withKey method. - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func (k *PrivateKeyECDSA) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } -func (k *PrivateKeyECDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { +func (k *PrivateKeyECDSA) withKey(f func(ossl.EVP_PKEY_PTR) error) error { defer runtime.KeepAlive(k) return f(k._pkey) } type PublicKeyECDSA struct { // _pkey MUST NOT be accessed directly. Instead, use the withKey method. - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func (k *PublicKeyECDSA) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } -func (k *PublicKeyECDSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { +func (k *PublicKeyECDSA) withKey(f func(ossl.EVP_PKEY_PTR) error) error { defer runtime.KeepAlive(k) return f(k._pkey) } @@ -61,42 +61,62 @@ func NewPrivateKeyECDSA(curve string, x, y, d BigInt) (*PrivateKeyECDSA, error) } func GenerateKeyECDSA(curve string) (x, y, d BigInt, err error) { + fail := func(err error) (BigInt, BigInt, BigInt, error) { + return nil, nil, nil, err + } // Generate the private key. - pkey, err := generateEVPPKey(C.GO_EVP_PKEY_EC, 0, curve) + pkey, err := generateEVPPKey(ossl.EVP_PKEY_EC, 0, curve) if err != nil { - return nil, nil, nil, err + return fail(err) } - defer C.go_openssl_EVP_PKEY_free(pkey) + defer ossl.EVP_PKEY_free(pkey) - var bx, by, bd C.GO_BIGNUM_PTR + var bx, by, bd ossl.BIGNUM_PTR defer func() { - C.go_openssl_BN_free(bx) - C.go_openssl_BN_free(by) + ossl.BN_free(bx) + ossl.BN_free(by) }() switch vMajor { case 1: // Retrieve the internal EC_KEY, which holds the X, Y, and D coordinates. key := getECKey(pkey) - group := C.go_openssl_EC_KEY_get0_group(key) - pt := C.go_openssl_EC_KEY_get0_public_key(key) + group, err := ossl.EC_KEY_get0_group(key) + if err != nil { + return fail(err) + } + pt, err := ossl.EC_KEY_get0_public_key(key) + if err != nil { + return fail(err) + } // Allocate two big numbers to store the X and Y coordinates. - bx, by = C.go_openssl_BN_new(), C.go_openssl_BN_new() - if bx == nil || by == nil { - return nil, nil, nil, newOpenSSLError("BN_new failed") + bx, err = ossl.BN_new() + if err != nil { + return fail(err) + } + by, err = ossl.BN_new() + if err != nil { + return fail(err) } // Get X and Y. - if C.go_openssl_EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil) == 0 { - return nil, nil, nil, newOpenSSLError("EC_POINT_get_affine_coordinates_GFp failed") + if err := ossl.EC_POINT_get_affine_coordinates_GFp(group, pt, bx, by, nil); err != nil { + return fail(err) } // Get Z. We don't need to free it, get0 does not increase the reference count. - bd = C.go_openssl_EC_KEY_get0_private_key(key) + bd, err = ossl.EC_KEY_get0_private_key(key) + if err != nil { + return fail(err) + } case 3: - if C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_EC_PUB_X, &bx) != 1 || - C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_EC_PUB_Y, &by) != 1 || - C.go_openssl_EVP_PKEY_get_bn_param(pkey, _OSSL_PKEY_PARAM_PRIV_KEY, &bd) != 1 { - return nil, nil, nil, newOpenSSLError("EVP_PKEY_get_bn_param") + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_EC_PUB_X, &bx); err != nil { + return fail(err) } - defer C.go_openssl_BN_clear_free(bd) + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_EC_PUB_Y, &by); err != nil { + return fail(err) + } + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_PRIV_KEY, &bd); err != nil { + return fail(err) + } + defer ossl.BN_clear_free(bd) default: panic(errUnsupportedVersion()) } @@ -121,16 +141,16 @@ func HashVerifyECDSA(pub *PublicKeyECDSA, h crypto.Hash, msg, sig []byte) bool { return evpHashVerify(pub.withKey, h, msg, sig) == nil } -func newECDSAKey(curve string, x, y, d BigInt) (C.GO_EVP_PKEY_PTR, error) { +func newECDSAKey(curve string, x, y, d BigInt) (ossl.EVP_PKEY_PTR, error) { nid, err := curveNID(curve) if err != nil { return nil, err } - var bx, by, bd C.GO_BIGNUM_PTR + var bx, by, bd ossl.BIGNUM_PTR defer func() { - C.go_openssl_BN_free(bx) - C.go_openssl_BN_free(by) - C.go_openssl_BN_clear_free(bd) + ossl.BN_free(bx) + ossl.BN_free(by) + ossl.BN_clear_free(bd) }() bx = bigToBN(x) by = bigToBN(y) @@ -148,38 +168,40 @@ func newECDSAKey(curve string, x, y, d BigInt) (C.GO_EVP_PKEY_PTR, error) { } } -func newECDSAKey1(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (pkey C.GO_EVP_PKEY_PTR, err error) { +func newECDSAKey1(nid int, bx, by, bd ossl.BIGNUM_PTR) (pkey ossl.EVP_PKEY_PTR, err error) { checkMajorVersion(1) - key := C.go_openssl_EC_KEY_new_by_curve_name(nid) - if key == nil { - return nil, newOpenSSLError("EC_KEY_new_by_curve_name failed") + key, err := ossl.EC_KEY_new_by_curve_name(int32(nid)) + if err != nil { + return nil, err } defer func() { if pkey == nil { - defer C.go_openssl_EC_KEY_free(key) + defer ossl.EC_KEY_free(key) } }() - if C.go_openssl_EC_KEY_set_public_key_affine_coordinates(key, bx, by) != 1 { - return nil, newOpenSSLError("EC_KEY_set_public_key_affine_coordinates failed") + if err := ossl.EC_KEY_set_public_key_affine_coordinates(key, bx, by); err != nil { + return nil, err } - if bd != nil && C.go_openssl_EC_KEY_set_private_key(key, bd) != 1 { - return nil, newOpenSSLError("EC_KEY_set_private_key failed") + if bd != nil { + if err := ossl.EC_KEY_set_private_key(key, bd); err != nil { + return nil, err + } } return newEVPPKEY(key) } -func newECDSAKey3(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (C.GO_EVP_PKEY_PTR, error) { +func newECDSAKey3(nid int, bx, by, bd ossl.BIGNUM_PTR) (ossl.EVP_PKEY_PTR, error) { checkMajorVersion(3) // Create the encoded public key public key from bx and by. - pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group C.GO_EC_GROUP_PTR) (C.GO_EC_POINT_PTR, error) { - pt := C.go_openssl_EC_POINT_new(group) - if pt == nil { - return nil, newOpenSSLError("EC_POINT_new") + pubBytes, err := generateAndEncodeEcPublicKey(nid, func(group ossl.EC_GROUP_PTR) (ossl.EC_POINT_PTR, error) { + pt, err := ossl.EC_POINT_new(group) + if err != nil { + return nil, err } - if C.go_openssl_EC_POINT_set_affine_coordinates(group, pt, bx, by, nil) != 1 { - C.go_openssl_EC_POINT_free(pt) + if err := ossl.EC_POINT_set_affine_coordinates(group, pt, bx, by, nil); err != nil { + ossl.EC_POINT_free(pt) return nil, newOpenSSLError("EC_POINT_set_affine_coordinates") } return pt, nil @@ -193,19 +215,19 @@ func newECDSAKey3(nid C.int, bx, by, bd C.GO_BIGNUM_PTR) (C.GO_EVP_PKEY_PTR, err return nil, err } defer bld.finalize() - bld.addUTF8String(_OSSL_PKEY_PARAM_GROUP_NAME, C.go_openssl_OBJ_nid2sn(nid), 0) - bld.addOctetString(_OSSL_PKEY_PARAM_PUB_KEY, pubBytes) - var selection C.int + bld.addUTF8String(ossl.OSSL_PKEY_PARAM_GROUP_NAME, ossl.OBJ_nid2sn(int32(nid)), 0) + bld.addOctetString(ossl.OSSL_PKEY_PARAM_PUB_KEY, pubBytes) + var selection int if bd != nil { - bld.addBN(_OSSL_PKEY_PARAM_PRIV_KEY, bd) - selection = C.GO_EVP_PKEY_KEYPAIR + bld.addBN(ossl.OSSL_PKEY_PARAM_PRIV_KEY, bd) + selection = ossl.EVP_PKEY_KEYPAIR } else { - selection = C.GO_EVP_PKEY_PUBLIC_KEY + selection = ossl.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) + defer ossl.OSSL_PARAM_free(params) + return newEvpFromParams(ossl.EVP_PKEY_EC, selection, params) } diff --git a/ecdsa_test.go b/ecdsa_test.go index 40186a79..2a805b5c 100644 --- a/ecdsa_test.go +++ b/ecdsa_test.go @@ -23,7 +23,6 @@ func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) { for _, test := range tests { curve := test.curve t.Run(test.name, func(t *testing.T) { - t.Parallel() f(t, curve) }) } diff --git a/ed25519.go b/ed25519.go index cd237025..f4b3e2dc 100644 --- a/ed25519.go +++ b/ed25519.go @@ -1,14 +1,14 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "errors" "runtime" "strconv" "sync" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) const ( @@ -29,16 +29,16 @@ 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) - if ctx != nil { - C.go_openssl_EVP_PKEY_CTX_free(ctx) + ctx, err := ossl.EVP_PKEY_CTX_new_id(ossl.EVP_PKEY_ED25519, nil) + if err == nil { + ossl.EVP_PKEY_CTX_free(ctx) return true } } case 3: - sig := C.go_openssl_EVP_SIGNATURE_fetch(nil, keyTypeED25519, nil) - if sig != nil { - C.go_openssl_EVP_SIGNATURE_free(sig) + sig, err := ossl.EVP_SIGNATURE_fetch(nil, cStringData(ossl.KeyTypeED25519), nil) + if err == nil { + ossl.EVP_SIGNATURE_free(sig) return true } } @@ -52,11 +52,11 @@ func SupportsEd25519() bool { } type PublicKeyEd25519 struct { - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func (k *PublicKeyEd25519) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } func (k *PublicKeyEd25519) Bytes() ([]byte, error) { @@ -69,11 +69,11 @@ func (k *PublicKeyEd25519) Bytes() ([]byte, error) { } type PrivateKeyEd25519 struct { - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func (k *PrivateKeyEd25519) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } func (k *PrivateKeyEd25519) Bytes() ([]byte, error) { @@ -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(ossl.EVP_PKEY_ED25519, 0, "") if err != nil { return nil, err } @@ -119,9 +119,9 @@ func NewPublicKeyEd25119(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))) - if pkey == nil { - return nil, newOpenSSLError("EVP_PKEY_new_raw_public_key") + pkey, err := ossl.EVP_PKEY_new_raw_public_key(ossl.EVP_PKEY_ED25519, nil, base(pub), len(pub)) + if err != nil { + return nil, err } pubk := &PublicKeyEd25519{_pkey: pkey} runtime.SetFinalizer(pubk, (*PublicKeyEd25519).finalize) @@ -135,36 +135,36 @@ 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))) - if pkey == nil { - return nil, newOpenSSLError("EVP_PKEY_new_raw_private_key") + pkey, err := ossl.EVP_PKEY_new_raw_private_key(ossl.EVP_PKEY_ED25519, nil, base(seed), len(seed)) + if err != nil { + return nil, err } priv := &PrivateKeyEd25519{_pkey: pkey} runtime.SetFinalizer(priv, (*PrivateKeyEd25519).finalize) return priv, nil } -func extractPKEYPubEd25519(pkey C.GO_EVP_PKEY_PTR, pub []byte) error { - r := C.go_openssl_EVP_PKEY_get_raw_public_key_wrapper(pkey, base(pub), C.size_t(publicKeySizeEd25519)) - if r.result != 1 { - return newOpenSSLError("EVP_PKEY_get_raw_public_key") +func extractPKEYPubEd25519(pkey ossl.EVP_PKEY_PTR, pub []byte) error { + keyLength, err := ossl.EVP_PKEY_get_raw_public_key_wrapper(pkey, base(pub), publicKeySizeEd25519) + if err != nil { + return err } - if r.len != publicKeySizeEd25519 { - return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(r.len))) + if keyLength != publicKeySizeEd25519 { + return errors.New("ed25519: bad public key length: " + strconv.Itoa(keyLength)) } return nil } -func extractPKEYPrivEd25519(pkey C.GO_EVP_PKEY_PTR, priv []byte) error { +func extractPKEYPrivEd25519(pkey ossl.EVP_PKEY_PTR, priv []byte) error { if err := extractPKEYPubEd25519(pkey, priv[seedSizeEd25519:]); err != nil { return err } - r := C.go_openssl_EVP_PKEY_get_raw_private_key_wrapper(pkey, base(priv), C.size_t(seedSizeEd25519)) - if r.result != 1 { - return newOpenSSLError("EVP_PKEY_get_raw_private_key") + keyLength, err := ossl.EVP_PKEY_get_raw_private_key_wrapper(pkey, base(priv), seedSizeEd25519) + if err != nil { + return err } - if r.len != seedSizeEd25519 { - return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(r.len))) + if keyLength != seedSizeEd25519 { + return errors.New("ed25519: bad private key length: " + strconv.Itoa(keyLength)) } return nil } @@ -182,20 +182,20 @@ func SignEd25519(priv *PrivateKeyEd25519, message []byte) (sig []byte, err error func signEd25519(priv *PrivateKeyEd25519, sig, message []byte) error { defer runtime.KeepAlive(priv) - ctx := C.go_openssl_EVP_MD_CTX_new() - if ctx == nil { - return newOpenSSLError("EVP_MD_CTX_new") + ctx, err := ossl.EVP_MD_CTX_new() + if err != nil { + return err } - defer C.go_openssl_EVP_MD_CTX_free(ctx) - if C.go_openssl_EVP_DigestSignInit(ctx, nil, nil, nil, priv._pkey) != 1 { - return newOpenSSLError("EVP_DigestSignInit") + defer ossl.EVP_MD_CTX_free(ctx) + if err := ossl.EVP_DigestSignInit(ctx, nil, nil, nil, priv._pkey); err != nil { + return err } - r := C.go_openssl_EVP_DigestSign_wrapper(ctx, base(sig), C.size_t(signatureSizeEd25519), base(message), C.size_t(len(message))) - if r.result != 1 { - return newOpenSSLError("EVP_DigestSign") + keyLength, err := ossl.EVP_DigestSign_wrapper(ctx, base(sig), signatureSizeEd25519, base(message), len(message)) + if err != nil { + return err } - if r.siglen != signatureSizeEd25519 { - return errors.New("ed25519: bad signature length: " + strconv.Itoa(int(r.siglen))) + if keyLength != signatureSizeEd25519 { + return errors.New("ed25519: bad signature length: " + strconv.Itoa(keyLength)) } return nil } @@ -203,15 +203,15 @@ func signEd25519(priv *PrivateKeyEd25519, sig, message []byte) error { // VerifyEd25519 reports whether sig is a valid signature of message by pub. func VerifyEd25519(pub *PublicKeyEd25519, message, sig []byte) error { defer runtime.KeepAlive(pub) - ctx := C.go_openssl_EVP_MD_CTX_new() - if ctx == nil { - return newOpenSSLError("EVP_MD_CTX_new") + ctx, err := ossl.EVP_MD_CTX_new() + if err != nil { + return err } - defer C.go_openssl_EVP_MD_CTX_free(ctx) - if C.go_openssl_EVP_DigestVerifyInit(ctx, nil, nil, nil, pub._pkey) != 1 { - return newOpenSSLError("EVP_DigestVerifyInit") + defer ossl.EVP_MD_CTX_free(ctx) + if err := ossl.EVP_DigestVerifyInit(ctx, nil, nil, nil, pub._pkey); err != nil { + return err } - if C.go_openssl_EVP_DigestVerify(ctx, base(sig), C.size_t(len(sig)), base(message), C.size_t(len(message))) != 1 { + if err := ossl.EVP_DigestVerify(ctx, base(sig), len(sig), base(message), len(message)); err != nil { return errors.New("ed25519: invalid signature") } return nil diff --git a/evp.go b/evp.go index 73f65c7c..5aace7ee 100644 --- a/evp.go +++ b/evp.go @@ -1,9 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto" "errors" @@ -11,12 +9,8 @@ import ( "strconv" "sync" "unsafe" -) -var ( - keyTypeRSA = C.CString("RSA") - keyTypeEC = C.CString("EC") - keyTypeED25519 = C.CString("ED25519") + "github.com/golang-fips/openssl/v2/internal/ossl" ) // cacheMD is a cache of crypto.Hash to GO_EVP_MD_PTR. @@ -47,7 +41,7 @@ func hashFuncHash(fn func() hash.Hash) (h hash.Hash, err error) { } // hashToMD converts a hash.Hash implementation from this package to a GO_EVP_MD_PTR. -func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { +func hashToMD(h hash.Hash) ossl.EVP_MD_PTR { var ch crypto.Hash switch h.(type) { case *sha1Hash, *sha1Marshal: @@ -77,7 +71,7 @@ func hashToMD(h hash.Hash) C.GO_EVP_MD_PTR { // hashFuncToMD converts a hash.Hash function to a GO_EVP_MD_PTR. // See [hashFuncHash] for details on error handling. -func hashFuncToMD(fn func() hash.Hash) (C.GO_EVP_MD_PTR, error) { +func hashFuncToMD(fn func() hash.Hash) (ossl.EVP_MD_PTR, error) { h, err := hashFuncHash(fn) if err != nil { return nil, err @@ -90,9 +84,9 @@ func hashFuncToMD(fn func() hash.Hash) (C.GO_EVP_MD_PTR, error) { } // cryptoHashToMD converts a crypto.Hash to a GO_EVP_MD_PTR. -func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { +func cryptoHashToMD(ch crypto.Hash) (md ossl.EVP_MD_PTR) { if v, ok := cacheMD.Load(ch); ok { - return v.(C.GO_EVP_MD_PTR) + return v.(ossl.EVP_MD_PTR) } defer func() { if md != nil { @@ -101,17 +95,17 @@ func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { // On OpenSSL 1 EVP_MD objects can be not-nil even // when they are not supported. We need to pass the md // to a EVP_MD_CTX to really know if they can be used. - ctx := C.go_openssl_EVP_MD_CTX_new() - if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { + ctx, _ := ossl.EVP_MD_CTX_new() + if ossl.EVP_DigestInit_ex(ctx, md, nil) != nil { md = nil } - C.go_openssl_EVP_MD_CTX_free(ctx) + ossl.EVP_MD_CTX_free(ctx) case 3: // On OpenSSL 3, directly operating on a EVP_MD object // not created by EVP_MD_fetch has negative performance // implications, as digest operations will have // to fetch it on every call. Better to just fetch it once here. - md = C.go_openssl_EVP_MD_fetch(nil, C.go_openssl_EVP_MD_get0_name(md), nil) + md, _ = ossl.EVP_MD_fetch(nil, ossl.EVP_MD_get0_name(md), nil) default: panic(errUnsupportedVersion()) } @@ -123,52 +117,52 @@ func cryptoHashToMD(ch crypto.Hash) (md C.GO_EVP_MD_PTR) { // still be used when signing/verifying with an RSA key. if ch == crypto.MD5SHA1 { if vMajor == 1 && vMinor == 0 { - return C.go_openssl_EVP_md5_sha1_backport() + return ossl.EVP_md5_sha1_backport() } else { - return C.go_openssl_EVP_md5_sha1() + return ossl.EVP_md5_sha1() } } switch ch { case crypto.MD4: - return C.go_openssl_EVP_md4() + return ossl.EVP_md4() case crypto.MD5: - return C.go_openssl_EVP_md5() + return ossl.EVP_md5() case crypto.SHA1: - return C.go_openssl_EVP_sha1() + return ossl.EVP_sha1() case crypto.SHA224: - return C.go_openssl_EVP_sha224() + return ossl.EVP_sha224() case crypto.SHA256: - return C.go_openssl_EVP_sha256() + return ossl.EVP_sha256() case crypto.SHA384: - return C.go_openssl_EVP_sha384() + return ossl.EVP_sha384() case crypto.SHA512: - return C.go_openssl_EVP_sha512() + return ossl.EVP_sha512() case crypto.SHA3_224: if versionAtOrAbove(1, 1, 1) { - return C.go_openssl_EVP_sha3_224() + return ossl.EVP_sha3_224() } case crypto.SHA3_256: if versionAtOrAbove(1, 1, 1) { - return C.go_openssl_EVP_sha3_256() + return ossl.EVP_sha3_256() } case crypto.SHA3_384: if versionAtOrAbove(1, 1, 1) { - return C.go_openssl_EVP_sha3_384() + return ossl.EVP_sha3_384() } case crypto.SHA3_512: if versionAtOrAbove(1, 1, 1) { - return C.go_openssl_EVP_sha3_512() + return ossl.EVP_sha3_512() } } return nil } // generateEVPPKey generates a new EVP_PKEY with the given id and properties. -func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error) { +func generateEVPPKey(id int, bits int, curve string) (ossl.EVP_PKEY_PTR, error) { if bits != 0 && curve != "" { return nil, fail("incorrect generateEVPPKey parameters") } - var curveID C.int + var curveID int if curve != "" { var err error curveID, err = curveNID(curve) @@ -176,43 +170,44 @@ func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error return nil, err } } - var pkey C.GO_EVP_PKEY_PTR + var pkey ossl.EVP_PKEY_PTR switch vMajor { case 1: - ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") + ctx, err := ossl.EVP_PKEY_CTX_new_id(int32(id), nil) + if err != nil { + return nil, err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - if C.go_openssl_EVP_PKEY_keygen_init(ctx) != 1 { - return nil, newOpenSSLError("EVP_PKEY_keygen_init") + defer ossl.EVP_PKEY_CTX_free(ctx) + if err := ossl.EVP_PKEY_keygen_init(ctx); err != nil { + return nil, err } if bits != 0 { - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS, C.int(bits), nil) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, int32(id), -1, ossl.EVP_PKEY_CTRL_RSA_KEYGEN_BITS, int32(bits), nil); err != nil { + return nil, err } } if curve != "" { - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, id, -1, C.GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, curveID, nil) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, int32(id), -1, ossl.EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, int32(curveID), nil); err != nil { + return nil, err } } - if C.go_openssl_EVP_PKEY_keygen(ctx, &pkey) != 1 { - return nil, newOpenSSLError("EVP_PKEY_keygen") + if err := ossl.EVP_PKEY_keygen(ctx, &pkey); err != nil { + return nil, err } case 3: + var err error switch id { - case C.GO_EVP_PKEY_RSA: - pkey = C.go_openssl_EVP_PKEY_Q_keygen_RSA(nil, nil, keyTypeRSA, C.size_t(bits)) - case C.GO_EVP_PKEY_EC: - pkey = C.go_openssl_EVP_PKEY_Q_keygen_EC(nil, nil, keyTypeEC, C.go_openssl_OBJ_nid2sn(curveID)) - case C.GO_EVP_PKEY_ED25519: - pkey = C.go_openssl_EVP_PKEY_Q_keygen(nil, nil, keyTypeED25519) + case ossl.EVP_PKEY_RSA: + pkey, err = ossl.EVP_PKEY_Q_keygen_RSA(nil, nil, cStringData(ossl.KeyTypeRSA), bits) + case ossl.EVP_PKEY_EC: + pkey, err = ossl.EVP_PKEY_Q_keygen_EC(nil, nil, cStringData(ossl.KeyTypeEC), ossl.OBJ_nid2sn(int32(curveID))) + case ossl.EVP_PKEY_ED25519: + pkey, err = ossl.EVP_PKEY_Q_keygen_ED25519(nil, nil, cStringData(ossl.KeyTypeED25519)) default: panic("unsupported key type '" + strconv.Itoa(int(id)) + "'") } - if pkey == nil { - return nil, newOpenSSLError("EVP_PKEY_Q_keygen") + if err != nil { + return nil, err } default: panic(errUnsupportedVersion()) @@ -221,26 +216,26 @@ func generateEVPPKey(id C.int, bits int, curve string) (C.GO_EVP_PKEY_PTR, error return pkey, nil } -type withKeyFunc func(func(C.GO_EVP_PKEY_PTR) C.int) C.int -type initFunc func(C.GO_EVP_PKEY_CTX_PTR) error -type cryptFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, *C.size_t, *C.uchar, C.size_t) error -type verifyFunc func(C.GO_EVP_PKEY_CTX_PTR, *C.uchar, C.size_t, *C.uchar, C.size_t) error +type withKeyFunc func(func(ossl.EVP_PKEY_PTR) error) error +type initFunc func(ossl.EVP_PKEY_CTX_PTR) error +type cryptFunc func(ossl.EVP_PKEY_CTX_PTR, *byte, *int, *byte, int) error +type verifyFunc func(ossl.EVP_PKEY_CTX_PTR, *byte, int, *byte, int) error -func setupEVP(withKey withKeyFunc, padding C.int, - h, mgfHash hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, - init initFunc) (_ C.GO_EVP_PKEY_CTX_PTR, err error) { - var ctx C.GO_EVP_PKEY_CTX_PTR - withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { - ctx = C.go_openssl_EVP_PKEY_CTX_new(pkey, nil) - return 1 +func setupEVP(withKey withKeyFunc, padding int, + h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash, + init initFunc) (_ ossl.EVP_PKEY_CTX_PTR, err error) { + var ctx ossl.EVP_PKEY_CTX_PTR + err = withKey(func(pkey ossl.EVP_PKEY_PTR) (err error) { + ctx, err = ossl.EVP_PKEY_CTX_new(pkey, nil) + return err }) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new failed") + if err != nil { + return nil, err } defer func() { if err != nil { if ctx != nil { - C.go_openssl_EVP_PKEY_CTX_free(ctx) + ossl.EVP_PKEY_CTX_free(ctx) ctx = nil } } @@ -254,18 +249,18 @@ func setupEVP(withKey withKeyFunc, padding C.int, // Each padding type has its own requirements in terms of when to apply the padding, // so it can't be just set at this point. setPadding := func() error { - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_PADDING, padding, nil) != 1 { - return newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_RSA, -1, ossl.EVP_PKEY_CTRL_RSA_PADDING, int32(padding), nil); err != nil { + return err } return nil } switch padding { - case C.GO_RSA_PKCS1_OAEP_PADDING: + case ossl.RSA_PKCS1_OAEP_PADDING: md := hashToMD(h) if md == nil { return nil, errors.New("crypto/rsa: unsupported hash function") } - var mgfMD C.GO_EVP_MD_PTR + var mgfMD ossl.EVP_MD_PTR if mgfHash != nil { // mgfHash is optional, but if it is set it must match a supported hash function. mgfMD = hashToMD(mgfHash) @@ -277,65 +272,58 @@ func setupEVP(withKey withKeyFunc, padding C.int, if err := setPadding(); err != nil { return nil, err } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_MD, 0, unsafe.Pointer(md)) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_RSA, -1, ossl.EVP_PKEY_CTRL_RSA_OAEP_MD, 0, unsafe.Pointer(md)); err != nil { + return nil, err } if mgfHash != nil { - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_MGF1_MD, 0, unsafe.Pointer(mgfMD)) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_RSA, -1, ossl.EVP_PKEY_CTRL_RSA_MGF1_MD, 0, unsafe.Pointer(mgfMD)); err != nil { + return nil, err } } // ctx takes ownership of label, so malloc a copy for OpenSSL to free. // OpenSSL does not take ownership of the label if the length is zero, // so better avoid the allocation. - var clabel *C.uchar if len(label) > 0 { - clabel = (*C.uchar)(cryptoMalloc(len(label))) + clabel := cryptoMalloc(len(label)) copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) var err error if vMajor == 3 { - ret := C.go_openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, unsafe.Pointer(clabel), C.int(len(label))) - if ret != 1 { - err = newOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") - } + err = ossl.EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, int32(len(label))) } else { - ret := C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL, C.int(len(label)), unsafe.Pointer(clabel)) - if ret != 1 { - err = newOpenSSLError("EVP_PKEY_CTX_ctrl failed") - } + err = ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_RSA, -1, ossl.EVP_PKEY_CTRL_RSA_OAEP_LABEL, int32(len(label)), clabel) } if err != nil { - cryptoFree(unsafe.Pointer(clabel)) + cryptoFree(clabel) return nil, err } } - case C.GO_RSA_PKCS1_PSS_PADDING: + case ossl.RSA_PKCS1_PSS_PADDING: md := cryptoHashToMD(ch) if md == nil { return nil, errors.New("crypto/rsa: unsupported hash function") } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_RSA, -1, ossl.EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)); err != nil { + return nil, err } // setPadding must happen after setting EVP_PKEY_CTRL_MD. if err := setPadding(); err != nil { return nil, err } if saltLen != 0 { - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, C.GO_EVP_PKEY_RSA, -1, C.GO_EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltLen, nil) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, ossl.EVP_PKEY_RSA, -1, ossl.EVP_PKEY_CTRL_RSA_PSS_SALTLEN, int32(saltLen), nil); err != nil { + return nil, err } } - case C.GO_RSA_PKCS1_PADDING: + case ossl.RSA_PKCS1_PADDING: if ch != 0 { // We support unhashed messages. md := cryptoHashToMD(ch) if md == nil { return nil, errors.New("crypto/rsa: unsupported hash function") } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, -1, C.GO_EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)) != 1 { - return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, -1, ossl.EVP_PKEY_CTRL_MD, 0, unsafe.Pointer(md)); err != nil { + return nil, err } if err := setPadding(); err != nil { return nil, err @@ -349,21 +337,23 @@ func setupEVP(withKey withKeyFunc, padding C.int, return ctx, nil } -func cryptEVP(withKey withKeyFunc, padding C.int, - h, mgfHash hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, +func cryptEVP(withKey withKeyFunc, padding int, + h, mgfHash hash.Hash, label []byte, saltLen int, ch crypto.Hash, init initFunc, crypt cryptFunc, in []byte) ([]byte, error) { ctx, err := setupEVP(withKey, padding, h, mgfHash, label, saltLen, ch, init) if err != nil { return nil, err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - pkeySize := withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { - return C.go_openssl_EVP_PKEY_get_size(pkey) + defer ossl.EVP_PKEY_CTX_free(ctx) + var pkeySize int + withKey(func(pkey ossl.EVP_PKEY_PTR) error { + pkeySize = int(ossl.EVP_PKEY_get_size(pkey)) + return nil }) - outLen := C.size_t(pkeySize) + outLen := pkeySize out := make([]byte, pkeySize) - if err := crypt(ctx, base(out), &outLen, base(in), C.size_t(len(in))); err != nil { + if err := crypt(ctx, base(out), &outLen, base(in), len(in)); err != nil { return nil, err } // The size returned by EVP_PKEY_get_size() is only preliminary and not exact, @@ -371,8 +361,8 @@ func cryptEVP(withKey withKeyFunc, padding C.int, return out[:outLen], nil } -func verifyEVP(withKey withKeyFunc, padding C.int, - h hash.Hash, label []byte, saltLen C.int, ch crypto.Hash, +func verifyEVP(withKey withKeyFunc, padding int, + h hash.Hash, label []byte, saltLen int, ch crypto.Hash, init initFunc, verify verifyFunc, sig, in []byte) error { @@ -380,72 +370,24 @@ func verifyEVP(withKey withKeyFunc, padding C.int, if err != nil { return err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - return verify(ctx, base(sig), C.size_t(len(sig)), base(in), C.size_t(len(in))) + defer ossl.EVP_PKEY_CTX_free(ctx) + return verify(ctx, base(sig), len(sig), base(in), len(in)) } -func evpEncrypt(withKey withKeyFunc, padding C.int, h, mgfHash hash.Hash, label, msg []byte) ([]byte, error) { - encryptInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { - if ret := C.go_openssl_EVP_PKEY_encrypt_init(ctx); ret != 1 { - return newOpenSSLError("EVP_PKEY_encrypt_init failed") - } - return nil - } - encrypt := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) error { - if ret := C.go_openssl_EVP_PKEY_encrypt(ctx, out, outLen, in, inLen); ret != 1 { - return newOpenSSLError("EVP_PKEY_encrypt failed") - } - return nil - } - return cryptEVP(withKey, padding, h, mgfHash, label, 0, 0, encryptInit, encrypt, msg) +func evpEncrypt(withKey withKeyFunc, padding int, h, mgfHash hash.Hash, label, msg []byte) ([]byte, error) { + return cryptEVP(withKey, padding, h, mgfHash, label, 0, 0, ossl.EVP_PKEY_encrypt_init, ossl.EVP_PKEY_encrypt, msg) } -func evpDecrypt(withKey withKeyFunc, padding C.int, h, mgfHash hash.Hash, label, msg []byte) ([]byte, error) { - decryptInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { - if ret := C.go_openssl_EVP_PKEY_decrypt_init(ctx); ret != 1 { - return newOpenSSLError("EVP_PKEY_decrypt_init failed") - } - return nil - } - decrypt := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) error { - if ret := C.go_openssl_EVP_PKEY_decrypt(ctx, out, outLen, in, inLen); ret != 1 { - return newOpenSSLError("EVP_PKEY_decrypt failed") - } - return nil - } - return cryptEVP(withKey, padding, h, mgfHash, label, 0, 0, decryptInit, decrypt, msg) +func evpDecrypt(withKey withKeyFunc, padding int, h, mgfHash hash.Hash, label, msg []byte) ([]byte, error) { + return cryptEVP(withKey, padding, h, mgfHash, label, 0, 0, ossl.EVP_PKEY_decrypt_init, ossl.EVP_PKEY_decrypt, msg) } -func evpSign(withKey withKeyFunc, padding C.int, saltLen C.int, h crypto.Hash, hashed []byte) ([]byte, error) { - signtInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { - if ret := C.go_openssl_EVP_PKEY_sign_init(ctx); ret != 1 { - return newOpenSSLError("EVP_PKEY_sign_init failed") - } - return nil - } - sign := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen *C.size_t, in *C.uchar, inLen C.size_t) error { - if ret := C.go_openssl_EVP_PKEY_sign(ctx, out, outLen, in, inLen); ret != 1 { - return newOpenSSLError("EVP_PKEY_sign failed") - } - return nil - } - return cryptEVP(withKey, padding, nil, nil, nil, saltLen, h, signtInit, sign, hashed) +func evpSign(withKey withKeyFunc, padding int, saltLen int, h crypto.Hash, hashed []byte) ([]byte, error) { + return cryptEVP(withKey, padding, nil, nil, nil, saltLen, h, ossl.EVP_PKEY_sign_init, ossl.EVP_PKEY_sign, hashed) } -func evpVerify(withKey withKeyFunc, padding C.int, saltLen C.int, h crypto.Hash, sig, hashed []byte) error { - verifyInit := func(ctx C.GO_EVP_PKEY_CTX_PTR) error { - if ret := C.go_openssl_EVP_PKEY_verify_init(ctx); ret != 1 { - return newOpenSSLError("EVP_PKEY_verify_init failed") - } - return nil - } - verify := func(ctx C.GO_EVP_PKEY_CTX_PTR, out *C.uchar, outLen C.size_t, in *C.uchar, inLen C.size_t) error { - if ret := C.go_openssl_EVP_PKEY_verify(ctx, out, outLen, in, inLen); ret != 1 { - return newOpenSSLError("EVP_PKEY_verify failed") - } - return nil - } - return verifyEVP(withKey, padding, nil, nil, saltLen, h, verifyInit, verify, sig, hashed) +func evpVerify(withKey withKeyFunc, padding int, saltLen int, h crypto.Hash, sig, hashed []byte) error { + return verifyEVP(withKey, padding, nil, nil, saltLen, h, ossl.EVP_PKEY_verify_init, ossl.EVP_PKEY_verify, sig, hashed) } func evpHashSign(withKey withKeyFunc, h crypto.Hash, msg []byte) ([]byte, error) { @@ -454,28 +396,28 @@ func evpHashSign(withKey withKeyFunc, h crypto.Hash, msg []byte) ([]byte, error) return nil, errors.New("unsupported hash function: " + strconv.Itoa(int(h))) } var out []byte - var outLen C.size_t - ctx := C.go_openssl_EVP_MD_CTX_new() - if ctx == nil { - return nil, newOpenSSLError("EVP_MD_CTX_new failed") + var outLen int + ctx, err := ossl.EVP_MD_CTX_new() + if err != nil { + return nil, err } - defer C.go_openssl_EVP_MD_CTX_free(ctx) - if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { - return C.go_openssl_EVP_DigestSignInit(ctx, nil, md, nil, key) - }) != 1 { - return nil, newOpenSSLError("EVP_DigestSignInit failed") + defer ossl.EVP_MD_CTX_free(ctx) + if err := withKey(func(key ossl.EVP_PKEY_PTR) error { + return ossl.EVP_DigestSignInit(ctx, nil, md, nil, key) + }); err != nil { + return nil, err } - if C.go_openssl_EVP_DigestUpdate(ctx, unsafe.Pointer(base(msg)), C.size_t(len(msg))) != 1 { - return nil, newOpenSSLError("EVP_DigestUpdate failed") + if err := ossl.EVP_DigestUpdate(ctx, unsafe.Pointer(base(msg)), len(msg)); err != nil { + return nil, err } // Obtain the signature length - if C.go_openssl_EVP_DigestSignFinal(ctx, nil, &outLen) != 1 { - return nil, newOpenSSLError("EVP_DigestSignFinal failed") + if err := ossl.EVP_DigestSignFinal(ctx, nil, &outLen); err != nil { + return nil, err } out = make([]byte, outLen) // Obtain the signature - if C.go_openssl_EVP_DigestSignFinal(ctx, base(out), &outLen) != 1 { - return nil, newOpenSSLError("EVP_DigestSignFinal failed") + if err := ossl.EVP_DigestSignFinal(ctx, base(out), &outLen); err != nil { + return nil, err } return out[:outLen], nil } @@ -485,33 +427,30 @@ func evpHashVerify(withKey withKeyFunc, h crypto.Hash, msg, sig []byte) error { if md == nil { return errors.New("unsupported hash function: " + strconv.Itoa(int(h))) } - ctx := C.go_openssl_EVP_MD_CTX_new() - if ctx == nil { - return newOpenSSLError("EVP_MD_CTX_new failed") - } - defer C.go_openssl_EVP_MD_CTX_free(ctx) - if withKey(func(key C.GO_EVP_PKEY_PTR) C.int { - return C.go_openssl_EVP_DigestVerifyInit(ctx, nil, md, nil, key) - }) != 1 { - return newOpenSSLError("EVP_DigestVerifyInit failed") + ctx, err := ossl.EVP_MD_CTX_new() + if err != nil { + return err } - if C.go_openssl_EVP_DigestUpdate(ctx, unsafe.Pointer(base(msg)), C.size_t(len(msg))) != 1 { - return newOpenSSLError("EVP_DigestUpdate failed") + defer ossl.EVP_MD_CTX_free(ctx) + if err := withKey(func(key ossl.EVP_PKEY_PTR) error { + return ossl.EVP_DigestVerifyInit(ctx, nil, md, nil, key) + }); err != nil { + return err } - if C.go_openssl_EVP_DigestVerifyFinal(ctx, base(sig), C.size_t(len(sig))) != 1 { - return newOpenSSLError("EVP_DigestVerifyFinal failed") + if err := ossl.EVP_DigestUpdate(ctx, unsafe.Pointer(base(msg)), len(msg)); err != nil { + return err } - return nil + return ossl.EVP_DigestVerifyFinal(ctx, base(sig), len(sig)) } -func newEVPPKEY(key C.GO_EC_KEY_PTR) (C.GO_EVP_PKEY_PTR, error) { - pkey := C.go_openssl_EVP_PKEY_new() - if pkey == nil { - return nil, newOpenSSLError("EVP_PKEY_new failed") +func newEVPPKEY(key ossl.EC_KEY_PTR) (ossl.EVP_PKEY_PTR, error) { + pkey, err := ossl.EVP_PKEY_new() + if err != nil { + return nil, err } - if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_EC, unsafe.Pointer(key)) != 1 { - C.go_openssl_EVP_PKEY_free(pkey) - return nil, newOpenSSLError("EVP_PKEY_assign failed") + if err := ossl.EVP_PKEY_assign(pkey, ossl.EVP_PKEY_EC, unsafe.Pointer(key)); err != nil { + ossl.EVP_PKEY_free(pkey) + return nil, err } return pkey, nil } @@ -519,13 +458,13 @@ func newEVPPKEY(key C.GO_EC_KEY_PTR) (C.GO_EVP_PKEY_PTR, error) { // getECKey returns the EC_KEY from pkey. // If pkey does not contain an EC_KEY it panics. // The returned key should not be freed. -func getECKey(pkey C.GO_EVP_PKEY_PTR) (key C.GO_EC_KEY_PTR) { +func getECKey(pkey ossl.EVP_PKEY_PTR) (key ossl.EC_KEY_PTR) { if vMajor == 1 && vMinor == 0 { - if key0 := C.go_openssl_EVP_PKEY_get0(pkey); key0 != nil { - key = C.GO_EC_KEY_PTR(key0) + if key0, err := ossl.EVP_PKEY_get0(pkey); err != nil { + key = ossl.EC_KEY_PTR(key0) } } else { - key = C.go_openssl_EVP_PKEY_get0_EC_KEY(pkey) + key, _ = ossl.EVP_PKEY_get0_EC_KEY(pkey) } if key == nil { panic("pkey does not contain an EC_KEY") @@ -533,18 +472,18 @@ func getECKey(pkey C.GO_EVP_PKEY_PTR) (key C.GO_EC_KEY_PTR) { return key } -func newEvpFromParams(id C.int, selection C.int, params C.GO_OSSL_PARAM_PTR) (C.GO_EVP_PKEY_PTR, error) { - ctx := C.go_openssl_EVP_PKEY_CTX_new_id(id, nil) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") - } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - if C.go_openssl_EVP_PKEY_fromdata_init(ctx) != 1 { - return nil, newOpenSSLError("EVP_PKEY_fromdata_init") - } - var pkey C.GO_EVP_PKEY_PTR - if C.go_openssl_EVP_PKEY_fromdata(ctx, &pkey, selection, params) != 1 { - return nil, newOpenSSLError("EVP_PKEY_fromdata") +func newEvpFromParams(id int, selection int, params ossl.OSSL_PARAM_PTR) (ossl.EVP_PKEY_PTR, error) { + ctx, err := ossl.EVP_PKEY_CTX_new_id(int32(id), nil) + if err != nil { + return nil, err + } + defer ossl.EVP_PKEY_CTX_free(ctx) + if err := ossl.EVP_PKEY_fromdata_init(ctx); err != nil { + return nil, err + } + var pkey ossl.EVP_PKEY_PTR + if err := ossl.EVP_PKEY_fromdata(ctx, &pkey, int32(selection), params); err != nil { + return nil, err } return pkey, nil } diff --git a/export_test.go b/export_test.go index f55857d0..2ff92957 100644 --- a/export_test.go +++ b/export_test.go @@ -5,13 +5,13 @@ import "sync" var ErrOpen = errOpen var SymCryptProviderAvailable = sync.OnceValue(func() bool { - return isProviderAvailable("symcryptprovider") + return isProviderAvailable("symcryptprovider\x00") }) var FIPSProviderAvailable = sync.OnceValue(func() bool { - return isProviderAvailable("fips") + return isProviderAvailable("fips\x00") }) var DefaultProviderAvailable = sync.OnceValue(func() bool { - return isProviderAvailable("default") + return isProviderAvailable("default\x00") }) diff --git a/goopenssl.c b/goopenssl.c deleted file mode 100644 index 626f184b..00000000 --- a/goopenssl.c +++ /dev/null @@ -1,248 +0,0 @@ -//go:build unix || windows - -#include "goopenssl.h" - -#ifdef _WIN32 -# include -# define dlsym (void*)GetProcAddress -#else -# include // dlsym -#endif -#include // fprintf - -// Approach taken from .Net System.Security.Cryptography.Native -// https://github.com/dotnet/runtime/blob/f64246ce08fb7a58221b2b7c8e68f69c02522b0d/src/libraries/Native/Unix/System.Security.Cryptography.Native/opensslshim.c - -#define DEFINEFUNC(ret, func, args, argscall) ret (*_g_##func)args; -#define DEFINEFUNC_LEGACY_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_1_1_1(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_3_0(ret, func, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_VARIADIC_3_0(ret, func, newname, args, argscall) DEFINEFUNC(ret, newname, args, argscall) - -FOR_ALL_OPENSSL_FUNCTIONS - -#undef DEFINEFUNC -#undef DEFINEFUNC_LEGACY_1_1 -#undef DEFINEFUNC_LEGACY_1_0 -#undef DEFINEFUNC_LEGACY_1 -#undef DEFINEFUNC_1_1 -#undef DEFINEFUNC_1_1_1 -#undef DEFINEFUNC_3_0 -#undef DEFINEFUNC_RENAMED_1_1 -#undef DEFINEFUNC_RENAMED_3_0 -#undef DEFINEFUNC_VARIADIC_3_0 - -// go_openssl_fips_enabled returns 1 if FIPS mode is enabled, 0 otherwise. -// As a special case, it returns -1 if it cannot determine if FIPS mode is enabled. -// See openssl.FIPS for details about its implementation. -// -// This function is reimplemented here because openssl.FIPS assumes that -// all the OpenSSL bindings are loaded, that is, go_openssl_load_functions has -// already been called. On the other hand, go_openssl_fips_enabled is called from -// openssl.CheckVersion, which is used to check if a given OpenSSL shared library -// exists and is FIPS compliant. That shared library might not be the one that -// was passed to go_openssl_load_functions, or it might not even have been called at all. -// -// It is written in C because it is not possible to directly call C function pointers -// retrieved using dlsym from Go. -int -go_openssl_fips_enabled(void* handle) -{ - // For OpenSSL 1.x. - int (*FIPS_mode)(void); - FIPS_mode = (int (*)(void))dlsym(handle, "FIPS_mode"); - if (FIPS_mode != NULL) - return FIPS_mode(); - - // For OpenSSL 3.x. - int (*EVP_default_properties_is_fips_enabled)(void*) = (int (*)(void*))dlsym(handle, "EVP_default_properties_is_fips_enabled"); - void *(*EVP_MD_fetch)(void*, const char*, const char*) = (void* (*)(void*, const char*, const char*))dlsym(handle, "EVP_MD_fetch"); - void (*EVP_MD_free)(void*) = (void (*)(void*))dlsym(handle, "EVP_MD_free"); - - if (EVP_default_properties_is_fips_enabled == NULL || EVP_MD_fetch == NULL || EVP_MD_free == NULL) { - // Shouldn't happen, but if it does, we can't determine if FIPS mode is enabled. - return -1; - } - - if (EVP_default_properties_is_fips_enabled(NULL) != 1) - return 0; - - void *md = EVP_MD_fetch(NULL, "SHA2-256", NULL); - if (md == NULL) - return 0; - - EVP_MD_free(md); - return 1; -} - -// Load all the functions stored in FOR_ALL_OPENSSL_FUNCTIONS -// and assign them to their corresponding function pointer -// defined in goopenssl.h. -void -go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch) -{ -#define DEFINEFUNC_INTERNAL(name, func) \ - _g_##name = dlsym(handle, func); \ - if (_g_##name == NULL) { \ - fprintf(stderr, "Cannot get required symbol " #func " from libcrypto version %u.%u\n", major, minor); \ - abort(); \ - } -#define DEFINEFUNC(ret, func, args, argscall) \ - DEFINEFUNC_INTERNAL(func, #func) -#define DEFINEFUNC_LEGACY_1_1(ret, func, args, argscall) \ - if (major == 1 && minor == 1) \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) \ - if (major == 1 && minor == 0) \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) \ - if (major == 1) \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_1_1(ret, func, args, argscall) \ - if (major == 3 || (major == 1 && minor == 1)) \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_1_1_1(ret, func, args, argscall) \ - if (major == 3 || (major == 1 && minor == 1 && patch == 1)) \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_3_0(ret, func, args, argscall) \ - if (major == 3) \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) \ - if (major == 1 && minor == 0) \ - { \ - DEFINEFUNC_INTERNAL(func, #oldfunc) \ - } \ - else \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ - if (major == 1) \ - { \ - DEFINEFUNC_INTERNAL(func, #oldfunc) \ - } \ - else \ - { \ - DEFINEFUNC_INTERNAL(func, #func) \ - } -#define DEFINEFUNC_VARIADIC_3_0(ret, func, newname, args, argscall) \ - if (major == 3) \ - { \ - DEFINEFUNC_INTERNAL(newname, #func) \ - } - -FOR_ALL_OPENSSL_FUNCTIONS - -#undef DEFINEFUNC -#undef DEFINEFUNC_LEGACY_1_1 -#undef DEFINEFUNC_LEGACY_1_0 -#undef DEFINEFUNC_LEGACY_1 -#undef DEFINEFUNC_1_1 -#undef DEFINEFUNC_1_1_1 -#undef DEFINEFUNC_3_0 -#undef DEFINEFUNC_RENAMED_1_1 -#undef DEFINEFUNC_RENAMED_3_0 -#undef DEFINEFUNC_VARIADIC_3_0 -} - -static unsigned long -version_num(void* handle) -{ - unsigned long (*fn)(void); - // OPENSSL_version_num is defined in OpenSSL 1.1.0 and 1.1.1. - fn = (unsigned long (*)(void))dlsym(handle, "OpenSSL_version_num"); - if (fn != NULL) - return fn(); - - // SSLeay is defined in OpenSSL 1.0.2. - fn = (unsigned long (*)(void))dlsym(handle, "SSLeay"); - if (fn != NULL) - return fn(); - - return 0; -} - -int -go_openssl_version_major(void* handle) -{ - unsigned int (*fn)(void); - // OPENSSL_version_major is supported since OpenSSL 3. - fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_major"); - if (fn != NULL) - return (int)fn(); - - // If OPENSSL_version_major is not defined, try with OpenSSL 1 functions. - unsigned long num = version_num(handle); - if (num < 0x10000000L || num >= 0x20000000L) - return -1; - - return 1; -} - -int -go_openssl_version_minor(void* handle) -{ - unsigned int (*fn)(void); - // OPENSSL_version_minor is supported since OpenSSL 3. - fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_minor"); - if (fn != NULL) - return (int)fn(); - - // If OPENSSL_version_minor is not defined, try with OpenSSL 1 functions. - unsigned long num = version_num(handle); - // OpenSSL version number follows this schema: - // MNNFFPPS: major minor fix patch status. - if (num < 0x10000000L || num >= 0x10200000L) - { - // We only support minor version 0 and 1, - // so there is no need to implement an algorithm - // that decodes the version number into individual components. - return -1; - } - - if (num >= 0x10100000L) - return 1; - - return 0; -} - -int -go_openssl_version_patch(void* handle) -{ - unsigned int (*fn)(void); - // OPENSSL_version_patch is supported since OpenSSL 3. - fn = (unsigned int (*)(void))dlsym(handle, "OPENSSL_version_patch"); - if (fn != NULL) - return (int)fn(); - - // If OPENSSL_version_patch is not defined, try with OpenSSL 1 functions. - unsigned long num = version_num(handle); - // OpenSSL version number follows this schema: - // MNNFFPPS: major minor fix patch status. - if (num < 0x10000000L || num >= 0x10200000L) - { - // We only support minor version 0 and 1, - // so there is no need to implement an algorithm - // that decodes the version number into individual components. - return -1; - } - - return (num >> 12) & 0xff; -} diff --git a/goopenssl.h b/goopenssl.h deleted file mode 100644 index 1165f991..00000000 --- a/goopenssl.h +++ /dev/null @@ -1,262 +0,0 @@ -// This header file describes the OpenSSL ABI as built for use in Go. - -#include // size_t - -#include "shims.h" - -// Suppress warnings about unused parameters. -#define UNUSED(x) (void)(x) - -static inline void -go_openssl_do_leak_check(void) -{ -#ifndef __has_feature -#define __has_feature(x) 0 -#endif - -#if (defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__) || \ - __has_feature(address_sanitizer) - extern void __lsan_do_leak_check(void); - __lsan_do_leak_check(); -#endif -} - -int go_openssl_fips_enabled(void* handle); -int go_openssl_version_major(void* handle); -int go_openssl_version_minor(void* handle); -int go_openssl_version_patch(void* handle); -int go_openssl_thread_setup(void); -void go_openssl_load_functions(void* handle, unsigned int major, unsigned int minor, unsigned int patch); -const GO_EVP_MD_PTR go_openssl_EVP_md5_sha1_backport(void); -void go_openssl_DSA_get0_pqg_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *p, GO_BIGNUM_PTR *q, GO_BIGNUM_PTR *g); -int go_openssl_DSA_set0_pqg_backport(GO_DSA_PTR d, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g); -void go_openssl_DSA_get0_key_backport(const GO_DSA_PTR d, GO_BIGNUM_PTR *pub_key, GO_BIGNUM_PTR *priv_key); -int go_openssl_DSA_set0_key_backport(GO_DSA_PTR d, GO_BIGNUM_PTR pub_key, GO_BIGNUM_PTR priv_key); - -// Define pointers to all the used OpenSSL functions. -// Calling C function pointers from Go is currently not supported. -// It is possible to circumvent this by using a C function wrapper. -// https://pkg.go.dev/cmd/cgo -#define DEFINEFUNC(ret, func, args, argscall) \ - extern ret (*_g_##func)args; \ - static inline ret go_openssl_##func args \ - { \ - return _g_##func argscall; \ - } -#define DEFINEFUNC_LEGACY_1_1(ret, func, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_LEGACY_1_0(ret, func, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_LEGACY_1(ret, func, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_1_1(ret, func, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_1_1_1(ret, func, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_3_0(ret, func, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_RENAMED_1_1(ret, func, oldfunc, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_RENAMED_3_0(ret, func, oldfunc, args, argscall) \ - DEFINEFUNC(ret, func, args, argscall) -#define DEFINEFUNC_VARIADIC_3_0(ret, func, newname, args, argscall) \ - DEFINEFUNC(ret, newname, args, argscall) - -FOR_ALL_OPENSSL_FUNCTIONS - -#undef DEFINEFUNC -#undef DEFINEFUNC_LEGACY_1_1 -#undef DEFINEFUNC_LEGACY_1_0 -#undef DEFINEFUNC_LEGACY_1 -#undef DEFINEFUNC_1_1 -#undef DEFINEFUNC_1_1_1 -#undef DEFINEFUNC_3_0 -#undef DEFINEFUNC_RENAMED_1_1 -#undef DEFINEFUNC_RENAMED_3_0 -#undef DEFINEFUNC_VARIADIC_3_0 - -// go_hash_sum copies ctx into ctx2 and calls EVP_DigestFinal using ctx2. -// This is necessary because Go hash.Hash mandates that Sum has no effect -// on the underlying stream. In particular it is OK to Sum, then Write more, -// then Sum again, and the second Sum acts as if the first didn't happen. -// It is written in C because Sum() tend to be in the hot path, -// and doing one cgo call instead of two is a significant performance win. -static inline int -go_hash_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out) -{ - if (go_openssl_EVP_MD_CTX_copy(ctx2, ctx) != 1) - return 0; - // TODO: use EVP_DigestFinal_ex once we know why it leaks - // memory on OpenSSL 1.0.2. - return go_openssl_EVP_DigestFinal(ctx2, out, NULL); -} - -// These wrappers allocate out_len on the C stack to avoid having to pass a pointer from Go, which would escape to the heap. -// Use them only in situations where the output length can be safely discarded. -static inline int -go_openssl_EVP_EncryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) -{ - int len; - return go_openssl_EVP_EncryptUpdate(ctx, out, &len, in, in_len); -} - -static inline int -go_openssl_EVP_DecryptUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) -{ - int len; - return go_openssl_EVP_DecryptUpdate(ctx, out, &len, in, in_len); -} - -static inline int -go_openssl_EVP_CipherUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, const unsigned char *in, int in_len) -{ - int len; - return go_openssl_EVP_CipherUpdate(ctx, out, &len, in, in_len); -} - -// These wrappers also allocate length variables on the C stack to avoid escape to the heap, but do return the result. -// A struct is returned that contains multiple return values instead of OpenSSL's approach of using pointers. - -typedef struct -{ - int result; - size_t keylen; -} go_openssl_EVP_PKEY_derive_wrapper_out; - -static inline go_openssl_EVP_PKEY_derive_wrapper_out -go_openssl_EVP_PKEY_derive_wrapper(GO_EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t keylen) -{ - go_openssl_EVP_PKEY_derive_wrapper_out r = {0, keylen}; - r.result = go_openssl_EVP_PKEY_derive(ctx, key, &r.keylen); - return r; -} - -typedef struct -{ - int result; - size_t len; -} go_openssl_EVP_PKEY_get_raw_key_out; - -static inline go_openssl_EVP_PKEY_get_raw_key_out -go_openssl_EVP_PKEY_get_raw_public_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t len) -{ - go_openssl_EVP_PKEY_get_raw_key_out r = {0, len}; - r.result = go_openssl_EVP_PKEY_get_raw_public_key(pkey, pub, &r.len); - return r; -} - -static inline go_openssl_EVP_PKEY_get_raw_key_out -go_openssl_EVP_PKEY_get_raw_private_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t len) -{ - go_openssl_EVP_PKEY_get_raw_key_out r = {0, len}; - r.result = go_openssl_EVP_PKEY_get_raw_private_key(pkey, priv, &r.len); - return r; -} - -typedef struct -{ - int result; - size_t siglen; -} go_openssl_EVP_DigestSign_wrapper_out; - -static inline go_openssl_EVP_DigestSign_wrapper_out -go_openssl_EVP_DigestSign_wrapper(GO_EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen) -{ - go_openssl_EVP_DigestSign_wrapper_out r = {0, siglen}; - r.result = go_openssl_EVP_DigestSign(ctx, sigret, &r.siglen, tbs, tbslen); - return r; -} - -// These wrappers allocate out_len on the C stack, and check that it matches the expected -// value, to avoid having to pass a pointer from Go, which would escape to the heap. - -static inline int -go_openssl_EVP_CIPHER_CTX_seal_wrapper(const GO_EVP_CIPHER_CTX_PTR ctx, - unsigned char *out, - const unsigned char *nonce, - const unsigned char *in, int in_len, - const unsigned char *aad, int aad_len) -{ - if (in_len == 0) in = (const unsigned char *)""; - if (aad_len == 0) aad = (const unsigned char *)""; - - if (go_openssl_EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) - return 0; - - int discard_len, out_len; - if (go_openssl_EVP_EncryptUpdate(ctx, NULL, &discard_len, aad, aad_len) != 1 - || go_openssl_EVP_EncryptUpdate(ctx, out, &out_len, in, in_len) != 1 - || go_openssl_EVP_EncryptFinal_ex(ctx, out + out_len, &discard_len) != 1) - { - return 0; - } - - if (in_len != out_len) - return 0; - - return go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_GET_TAG, 16, out + out_len); -} - -static inline int -go_openssl_EVP_CIPHER_CTX_open_wrapper(const GO_EVP_CIPHER_CTX_PTR ctx, - unsigned char *out, - const unsigned char *nonce, - const unsigned char *in, int in_len, - const unsigned char *aad, int aad_len, - const unsigned char *tag) -{ - if (in_len == 0) { - in = (const unsigned char *)""; - // OpenSSL 1.0.2 in FIPS mode contains a bug: it will fail to verify - // unless EVP_DecryptUpdate is called at least once with a non-NULL - // output buffer. OpenSSL will not dereference the output buffer when - // the input length is zero, so set it to an arbitrary non-NULL pointer - // to satisfy OpenSSL when the caller only has authenticated additional - // data (AAD) to verify. While a stack-allocated buffer could be used, - // that would risk a stack-corrupting buffer overflow if OpenSSL - // unexpectedly dereferenced it. Instead pass a value which would - // segfault if dereferenced on any modern platform where a NULL-pointer - // dereference would also segfault. - if (out == NULL) out = (unsigned char *)1; - } - if (aad_len == 0) aad = (const unsigned char *)""; - - if (go_openssl_EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, nonce) != 1) - return 0; - - // OpenSSL 1.0.x FIPS Object Module 2.0 versions below 2.0.5 require that - // the tag be set before the ciphertext, otherwise EVP_DecryptUpdate returns - // an error. At least one extant commercially-supported, FIPS validated - // build of OpenSSL 1.0.2 uses FIPS module version 2.0.1. Set the tag first - // to maximize compatibility with all OpenSSL version combinations. - if (go_openssl_EVP_CIPHER_CTX_ctrl(ctx, GO_EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)(tag)) != 1) - return 0; - - int discard_len, out_len; - if (go_openssl_EVP_DecryptUpdate(ctx, NULL, &discard_len, aad, aad_len) != 1 - || go_openssl_EVP_DecryptUpdate(ctx, out, &out_len, in, in_len) != 1) - { - return 0; - } - - if (go_openssl_EVP_DecryptFinal_ex(ctx, out + out_len, &discard_len) != 1) - return 0; - - if (out_len != in_len) - return 0; - - return 1; -} - -// Hand-roll custom wrappers for CRYPTO_malloc and CRYPTO_free which cast the -// function pointers to the correct signatures for OpenSSL 1.0.2. - -static inline void * -go_openssl_CRYPTO_malloc_legacy102(int num, const char *file, int line) { - return ((void *(*)(int, const char *, int))_g_CRYPTO_malloc)(num, file, line); -} - -static inline void -go_openssl_CRYPTO_free_legacy102(void *str) { - ((void (*)(void *))_g_CRYPTO_free)(str); -} \ No newline at end of file diff --git a/hash.go b/hash.go index 6fd3a518..5b90b790 100644 --- a/hash.go +++ b/hash.go @@ -1,9 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto" "errors" @@ -12,6 +10,8 @@ import ( "strconv" "sync" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) // NOTE: Implementation ported from https://go-review.googlesource.com/c/go/+/404295. @@ -26,7 +26,13 @@ import ( // This is all to preserve compatibility with the allocation behavior of the non-openssl implementations. func hashOneShot(ch crypto.Hash, p []byte, sum []byte) bool { - return C.go_openssl_EVP_Digest(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), (*C.uchar)(unsafe.Pointer(&*addr(sum))), nil, cryptoHashToMD(ch), nil) != 0 + d := unsafe.Pointer(addr(p)) + s := unsafe.Pointer(addr(sum)) + var pinner runtime.Pinner + pinner.Pin(d) + pinner.Pin(s) + defer pinner.Unpin() + return ossl.EVP_Digest(d, len(p), (*byte)(s), nil, cryptoHashToMD(ch), nil) == nil } func MD4(p []byte) (sum [16]byte) { @@ -126,15 +132,12 @@ func isHashMarshallable(ch crypto.Hash) bool { if md == nil { return false } - prov := C.go_openssl_EVP_MD_get0_provider(md) - if prov == nil { - return false - } - cname := C.go_openssl_OSSL_PROVIDER_get0_name(prov) - if cname == nil { + prov, err := ossl.EVP_MD_get0_provider(md) + if err != nil { return false } - name := C.GoString(cname) + cname := ossl.OSSL_PROVIDER_get0_name(prov) + name := goString(cname) // We only know the memory layout of the built-in providers. // See evpHash.hashState for more details. marshallable := name == "default" || name == "fips" @@ -144,14 +147,15 @@ func isHashMarshallable(ch crypto.Hash) bool { // evpHash implements generic hash methods. type evpHash struct { - ctx C.GO_EVP_MD_CTX_PTR + ctx ossl.EVP_MD_CTX_PTR // ctx2 is used in evpHash.sum to avoid changing // the state of ctx. Having it here allows reusing the // same allocated object multiple times. - ctx2 C.GO_EVP_MD_CTX_PTR + ctx2 ossl.EVP_MD_CTX_PTR size int blockSize int marshallable bool + pinner runtime.Pinner } func newEvpHash(ch crypto.Hash) *evpHash { @@ -159,18 +163,25 @@ func newEvpHash(ch crypto.Hash) *evpHash { if md == nil { panic("openssl: unsupported hash function: " + strconv.Itoa(int(ch))) } - ctx := C.go_openssl_EVP_MD_CTX_new() - if C.go_openssl_EVP_DigestInit_ex(ctx, md, nil) != 1 { - C.go_openssl_EVP_MD_CTX_free(ctx) - panic(newOpenSSLError("EVP_DigestInit_ex")) + ctx, err := ossl.EVP_MD_CTX_new() + if err != nil { + panic(err) + } + if err := ossl.EVP_DigestInit_ex(ctx, md, nil); err != nil { + ossl.EVP_MD_CTX_free(ctx) + panic(err) + } + ctx2, err := ossl.EVP_MD_CTX_new() + if err != nil { + ossl.EVP_MD_CTX_free(ctx) + panic(err) } - ctx2 := C.go_openssl_EVP_MD_CTX_new() - blockSize := int(C.go_openssl_EVP_MD_get_block_size(md)) + blockSize := ossl.EVP_MD_get_block_size(md) h := &evpHash{ ctx: ctx, ctx2: ctx2, size: ch.Size(), - blockSize: blockSize, + blockSize: int(blockSize), marshallable: isHashMarshallable(ch), } runtime.SetFinalizer(h, (*evpHash).finalize) @@ -178,38 +189,47 @@ func newEvpHash(ch crypto.Hash) *evpHash { } func (h *evpHash) finalize() { - C.go_openssl_EVP_MD_CTX_free(h.ctx) - C.go_openssl_EVP_MD_CTX_free(h.ctx2) + ossl.EVP_MD_CTX_free(h.ctx) + ossl.EVP_MD_CTX_free(h.ctx2) } func (h *evpHash) Reset() { // There is no need to reset h.ctx2 because it is always reset after // use in evpHash.sum. - if C.go_openssl_EVP_DigestInit_ex(h.ctx, nil, nil) != 1 { - panic(newOpenSSLError("EVP_DigestInit_ex")) + if err := ossl.EVP_DigestInit_ex(h.ctx, nil, nil); err != nil { + panic(err) } runtime.KeepAlive(h) } func (h *evpHash) Write(p []byte) (int, error) { - if len(p) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&*addr(p)), C.size_t(len(p))) != 1 { - panic(newOpenSSLError("EVP_DigestUpdate")) + if len(p) == 0 { + return 0, nil + } + d := unsafe.Pointer(addr(p)) + h.pinner.Pin(d) + defer h.pinner.Unpin() + if err := ossl.EVP_DigestUpdate(h.ctx, d, len(p)); err != nil { + panic(err) } runtime.KeepAlive(h) return len(p), nil } func (h *evpHash) WriteString(s string) (int, error) { - if len(s) > 0 && C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(unsafe.StringData(s)), C.size_t(len(s))) == 0 { - panic("openssl: EVP_DigestUpdate failed") + if len(s) == 0 { + return 0, nil + } + if err := ossl.EVP_DigestUpdate(h.ctx, (unsafe.Pointer)(unsafe.StringData(s)), len(s)); err != nil { + panic(err) } runtime.KeepAlive(h) return len(s), nil } func (h *evpHash) WriteByte(c byte) error { - if C.go_openssl_EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1) == 0 { - panic("openssl: EVP_DigestUpdate failed") + if err := ossl.EVP_DigestUpdate(h.ctx, unsafe.Pointer(&c), 1); err != nil { + panic(err) } runtime.KeepAlive(h) return nil @@ -224,8 +244,8 @@ func (h *evpHash) BlockSize() int { } func (h *evpHash) sum(out []byte) { - if C.go_hash_sum(h.ctx, h.ctx2, base(out)) != 1 { - panic(newOpenSSLError("go_hash_sum")) + if err := ossl.HashSum(h.ctx, h.ctx2, base(out)); err != nil { + panic(err) } runtime.KeepAlive(h) } @@ -234,18 +254,18 @@ func (h *evpHash) sum(out []byte) { // The duplicate object contains all state and data contained in the // original object at the point of duplication. func (h *evpHash) clone() (*evpHash, error) { - ctx := C.go_openssl_EVP_MD_CTX_new() - if ctx == nil { - return nil, newOpenSSLError("EVP_MD_CTX_new") + ctx, err := ossl.EVP_MD_CTX_new() + if err != nil { + return nil, err } - if C.go_openssl_EVP_MD_CTX_copy_ex(ctx, h.ctx) != 1 { - C.go_openssl_EVP_MD_CTX_free(ctx) - return nil, newOpenSSLError("EVP_MD_CTX_copy") + if err := ossl.EVP_MD_CTX_copy_ex(ctx, h.ctx); err != nil { + ossl.EVP_MD_CTX_free(ctx) + return nil, err } - ctx2 := C.go_openssl_EVP_MD_CTX_new() - if ctx2 == nil { - C.go_openssl_EVP_MD_CTX_free(ctx) - return nil, newOpenSSLError("EVP_MD_CTX_new") + ctx2, err := ossl.EVP_MD_CTX_new() + if err != nil { + ossl.EVP_MD_CTX_free(ctx) + return nil, err } cloned := &evpHash{ ctx: ctx, @@ -271,7 +291,7 @@ func (h *evpHash) hashState() unsafe.Pointer { // https://github.com/openssl/openssl/blob/0418e993c717a6863f206feaa40673a261de7395/crypto/evp/evp_local.h#L12. type mdCtx struct { _ [2]unsafe.Pointer - _ C.ulong + _ uint64 md_data unsafe.Pointer } return (*mdCtx)(unsafe.Pointer(h.ctx)).md_data @@ -279,7 +299,7 @@ func (h *evpHash) hashState() unsafe.Pointer { // https://github.com/openssl/openssl/blob/5675a5aaf6a2e489022bcfc18330dae9263e598e/crypto/evp/evp_local.h#L16. type mdCtx struct { _ [3]unsafe.Pointer - _ C.ulong + _ uint64 _ [3]unsafe.Pointer algctx unsafe.Pointer } diff --git a/hkdf.go b/hkdf.go index d4f8aa6a..8f098ac4 100644 --- a/hkdf.go +++ b/hkdf.go @@ -1,9 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "errors" "hash" @@ -11,6 +9,8 @@ import ( "runtime" "sync" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) // SupprtHKDF reports whether the current OpenSSL version supports HKDF. @@ -26,53 +26,53 @@ func SupportsHKDF() bool { } } -func newHKDFCtx1(md C.GO_EVP_MD_PTR, mode C.int, secret, salt, pseudorandomKey, info []byte) (ctx C.GO_EVP_PKEY_CTX_PTR, err error) { +func newHKDFCtx1(md ossl.EVP_MD_PTR, mode int, secret, salt, pseudorandomKey, info []byte) (ctx ossl.EVP_PKEY_CTX_PTR, err error) { checkMajorVersion(1) - ctx = C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_HKDF, nil) - if ctx == nil { - return nil, newOpenSSLError("EVP_PKEY_CTX_new_id") + ctx, err = ossl.EVP_PKEY_CTX_new_id(ossl.EVP_PKEY_HKDF, nil) + if err != nil { + return nil, err } defer func() { if err != nil { - C.go_openssl_EVP_PKEY_CTX_free(ctx) + ossl.EVP_PKEY_CTX_free(ctx) } }() - if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_derive_init") + if err := ossl.EVP_PKEY_derive_init(ctx); err != nil { + return ctx, err } - ctrlSlice := func(ctrl int, data []byte) C.int { + ctrlSlice := func(ctrl int, data []byte) error { if len(data) == 0 { - return 1 // No data to set. + return nil // No data to set. } - return C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, C.int(ctrl), C.int(len(data)), unsafe.Pointer(base(data))) + return ossl.EVP_PKEY_CTX_ctrl(ctx, -1, ossl.GO1_EVP_PKEY_OP_DERIVE, int32(ctrl), int32(len(data)), unsafe.Pointer(base(data))) } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, C.GO_EVP_PKEY_CTRL_HKDF_MODE, mode, nil) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_mode") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, ossl.GO1_EVP_PKEY_OP_DERIVE, ossl.EVP_PKEY_CTRL_HKDF_MODE, int32(mode), nil); err != nil { + return ctx, err } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, C.GO1_EVP_PKEY_OP_DERIVE, C.GO_EVP_PKEY_CTRL_HKDF_MD, 0, unsafe.Pointer(md)) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_CTX_set_hkdf_md") + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, ossl.GO1_EVP_PKEY_OP_DERIVE, ossl.EVP_PKEY_CTRL_HKDF_MD, 0, unsafe.Pointer(md)); err != nil { + return ctx, err } - if ctrlSlice(C.GO_EVP_PKEY_CTRL_HKDF_KEY, secret) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") + if err := ctrlSlice(ossl.EVP_PKEY_CTRL_HKDF_KEY, secret); err != nil { + return ctx, err } - if ctrlSlice(C.GO_EVP_PKEY_CTRL_HKDF_SALT, salt) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_salt") + if err := ctrlSlice(ossl.EVP_PKEY_CTRL_HKDF_SALT, salt); err != nil { + return ctx, err } - if ctrlSlice(C.GO_EVP_PKEY_CTRL_HKDF_KEY, pseudorandomKey) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_CTX_set1_hkdf_key") + if err := ctrlSlice(ossl.EVP_PKEY_CTRL_HKDF_KEY, pseudorandomKey); err != nil { + return ctx, err } - if ctrlSlice(C.GO_EVP_PKEY_CTRL_HKDF_INFO, info) != 1 { - return ctx, newOpenSSLError("EVP_PKEY_CTX_add1_hkdf_info") + if err := ctrlSlice(ossl.EVP_PKEY_CTRL_HKDF_INFO, info); err != nil { + return ctx, err } return ctx, nil } type hkdf1 struct { - ctx C.GO_EVP_PKEY_CTX_PTR + ctx ossl.EVP_PKEY_CTX_PTR hashLen int buf []byte @@ -80,7 +80,7 @@ type hkdf1 struct { func (c *hkdf1) finalize() { if c.ctx != nil { - C.go_openssl_EVP_PKEY_CTX_free(c.ctx) + ossl.EVP_PKEY_CTX_free(c.ctx) } } @@ -101,9 +101,9 @@ func (c *hkdf1) Read(p []byte) (int, error) { return 0, errors.New("hkdf: entropy limit reached") } c.buf = append(c.buf, make([]byte, needLen)...) - outLen := C.size_t(prevLen + needLen) - if C.go_openssl_EVP_PKEY_derive_wrapper(c.ctx, base(c.buf), outLen).result != 1 { - return 0, newOpenSSLError("EVP_PKEY_derive") + outLen := prevLen + needLen + if _, err := ossl.EVP_PKEY_derive_wrapper(c.ctx, base(c.buf), outLen); err != nil { + return 0, err } n := copy(p, c.buf[prevLen:outLen]) return n, nil @@ -121,29 +121,33 @@ func ExtractHKDF(h func() hash.Hash, secret, salt []byte) ([]byte, error) { switch vMajor { case 1: - ctx, err := newHKDFCtx1(md, C.GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY, secret, salt, nil, nil) + ctx, err := newHKDFCtx1(md, ossl.EVP_KDF_HKDF_MODE_EXTRACT_ONLY, secret, salt, nil, nil) if err != nil { return nil, err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - r := C.go_openssl_EVP_PKEY_derive_wrapper(ctx, nil, 0) - if r.result != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive_init") + defer ossl.EVP_PKEY_CTX_free(ctx) + keyLength, err := ossl.EVP_PKEY_derive_wrapper(ctx, nil, 0) + if err != nil { + return nil, err } - out := make([]byte, r.keylen) - if C.go_openssl_EVP_PKEY_derive_wrapper(ctx, base(out), r.keylen).result != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive") + out := make([]byte, keyLength) + if _, err := ossl.EVP_PKEY_derive_wrapper(ctx, base(out), keyLength); err != nil { + return nil, err } - return out[:r.keylen], nil + return out, nil case 3: - ctx, err := newHKDFCtx3(md, C.GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY, secret, salt, nil, nil) + ctx, err := newHKDFCtx3(md, ossl.EVP_KDF_HKDF_MODE_EXTRACT_ONLY, secret, salt, nil, nil) + if err != nil { + return nil, err + } + defer ossl.EVP_KDF_CTX_free(ctx) + size, err := ossl.EVP_KDF_CTX_get_kdf_size(ctx) if err != nil { return nil, err } - defer C.go_openssl_EVP_KDF_CTX_free(ctx) - out := make([]byte, C.go_openssl_EVP_KDF_CTX_get_kdf_size(ctx)) - if C.go_openssl_EVP_KDF_derive(ctx, base(out), C.size_t(len(out)), nil) != 1 { - return nil, newOpenSSLError("EVP_KDF_derive") + out := make([]byte, size) + if err := ossl.EVP_KDF_derive(ctx, base(out), len(out), nil); err != nil { + return nil, err } return out, nil default: @@ -165,22 +169,22 @@ func ExpandHKDFOneShot(h func() hash.Hash, pseudorandomKey, info []byte, keyLeng out := make([]byte, keyLength) switch vMajor { case 1: - ctx, err := newHKDFCtx1(md, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) + ctx, err := newHKDFCtx1(md, ossl.EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) if err != nil { return nil, err } - defer C.go_openssl_EVP_PKEY_CTX_free(ctx) - if C.go_openssl_EVP_PKEY_derive_wrapper(ctx, base(out), C.size_t(keyLength)).result != 1 { - return nil, newOpenSSLError("EVP_PKEY_derive") + defer ossl.EVP_PKEY_CTX_free(ctx) + if _, err := ossl.EVP_PKEY_derive_wrapper(ctx, base(out), keyLength); err != nil { + return nil, err } case 3: - ctx, err := newHKDFCtx3(md, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) + ctx, err := newHKDFCtx3(md, ossl.EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) if err != nil { return nil, err } - defer C.go_openssl_EVP_KDF_CTX_free(ctx) - if C.go_openssl_EVP_KDF_derive(ctx, base(out), C.size_t(keyLength), nil) != 1 { - return nil, newOpenSSLError("EVP_KDF_derive") + defer ossl.EVP_KDF_CTX_free(ctx) + if err := ossl.EVP_KDF_derive(ctx, base(out), keyLength, nil); err != nil { + return nil, err } default: panic(errUnsupportedVersion()) @@ -200,19 +204,19 @@ func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, er switch vMajor { case 1: - ctx, err := newHKDFCtx1(md, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) + ctx, err := newHKDFCtx1(md, ossl.EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) if err != nil { return nil, err } - c := &hkdf1{ctx: ctx, hashLen: int(C.go_openssl_EVP_MD_get_size(md))} + c := &hkdf1{ctx: ctx, hashLen: int(ossl.EVP_MD_get_size(md))} runtime.SetFinalizer(c, (*hkdf1).finalize) return c, nil case 3: - ctx, err := newHKDFCtx3(md, C.GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) + ctx, err := newHKDFCtx3(md, ossl.EVP_KDF_HKDF_MODE_EXPAND_ONLY, nil, nil, pseudorandomKey, info) if err != nil { return nil, err } - c := &hkdf3{ctx: ctx, hashLen: int(C.go_openssl_EVP_MD_get_size(md))} + c := &hkdf3{ctx: ctx, hashLen: int(ossl.EVP_MD_get_size(md))} runtime.SetFinalizer(c, (*hkdf3).finalize) return c, nil default: @@ -221,7 +225,7 @@ func ExpandHKDF(h func() hash.Hash, pseudorandomKey, info []byte) (io.Reader, er } type hkdf3 struct { - ctx C.GO_EVP_KDF_CTX_PTR + ctx ossl.EVP_KDF_CTX_PTR hashLen int buf []byte @@ -229,40 +233,38 @@ type hkdf3 struct { func (c *hkdf3) finalize() { if c.ctx != nil { - C.go_openssl_EVP_KDF_CTX_free(c.ctx) + ossl.EVP_KDF_CTX_free(c.ctx) } } // fetchHKDF3 fetches the HKDF algorithm. // It is safe to call this function concurrently. // The returned EVP_KDF_PTR shouldn't be freed. -var fetchHKDF3 = sync.OnceValues(func() (C.GO_EVP_KDF_PTR, error) { +var fetchHKDF3 = sync.OnceValues(func() (ossl.EVP_KDF_PTR, error) { checkMajorVersion(3) - name := C.CString("HKDF") - kdf := C.go_openssl_EVP_KDF_fetch(nil, name, nil) - C.free(unsafe.Pointer(name)) - if kdf == nil { - return nil, newOpenSSLError("EVP_KDF_fetch") + kdf, err := ossl.EVP_KDF_fetch(nil, cStringData(ossl.OSSL_KDF_NAME_HKDF), nil) + if err != nil { + return nil, err } return kdf, nil }) // newHKDFCtx3 implements HKDF for OpenSSL 3 using the EVP_KDF API. -func newHKDFCtx3(md C.GO_EVP_MD_PTR, mode C.int, secret, salt, pseudorandomKey, info []byte) (_ C.GO_EVP_KDF_CTX_PTR, err error) { +func newHKDFCtx3(md ossl.EVP_MD_PTR, mode int, secret, salt, pseudorandomKey, info []byte) (_ ossl.EVP_KDF_CTX_PTR, err error) { checkMajorVersion(3) kdf, err := fetchHKDF3() if err != nil { return nil, err } - ctx := C.go_openssl_EVP_KDF_CTX_new(kdf) - if ctx == nil { - return nil, newOpenSSLError("EVP_KDF_CTX_new") + ctx, err := ossl.EVP_KDF_CTX_new(kdf) + if err != nil { + return nil, err } defer func() { if err != nil { - C.go_openssl_EVP_KDF_CTX_free(ctx) + ossl.EVP_KDF_CTX_free(ctx) } }() @@ -270,28 +272,28 @@ func newHKDFCtx3(md C.GO_EVP_MD_PTR, mode C.int, secret, salt, pseudorandomKey, if err != nil { return ctx, err } - bld.addUTF8String(_OSSL_KDF_PARAM_DIGEST, C.go_openssl_EVP_MD_get0_name(md), 0) - bld.addInt32(_OSSL_KDF_PARAM_MODE, int32(mode)) + bld.addUTF8String(ossl.OSSL_KDF_PARAM_DIGEST, ossl.EVP_MD_get0_name(md), 0) + bld.addInt32(ossl.OSSL_KDF_PARAM_MODE, int32(mode)) if len(secret) > 0 { - bld.addOctetString(_OSSL_KDF_PARAM_KEY, secret) + bld.addOctetString(ossl.OSSL_KDF_PARAM_KEY, secret) } if len(salt) > 0 { - bld.addOctetString(_OSSL_KDF_PARAM_SALT, salt) + bld.addOctetString(ossl.OSSL_KDF_PARAM_SALT, salt) } if len(pseudorandomKey) > 0 { - bld.addOctetString(_OSSL_KDF_PARAM_KEY, pseudorandomKey) + bld.addOctetString(ossl.OSSL_KDF_PARAM_KEY, pseudorandomKey) } if len(info) > 0 { - bld.addOctetString(_OSSL_KDF_PARAM_INFO, info) + bld.addOctetString(ossl.OSSL_KDF_PARAM_INFO, info) } params, err := bld.build() if err != nil { return ctx, err } - defer C.go_openssl_OSSL_PARAM_free(params) + defer ossl.OSSL_PARAM_free(params) - if C.go_openssl_EVP_KDF_CTX_set_params(ctx, params) != 1 { - return ctx, newOpenSSLError("EVP_KDF_CTX_set_params") + if err := ossl.EVP_KDF_CTX_set_params(ctx, params); err != nil { + return ctx, err } return ctx, nil } @@ -313,9 +315,9 @@ func (c *hkdf3) Read(p []byte) (int, error) { return 0, errors.New("hkdf: entropy limit reached") } c.buf = append(c.buf, make([]byte, needLen)...) - outLen := C.size_t(prevLen + needLen) - if C.go_openssl_EVP_KDF_derive(c.ctx, base(c.buf), outLen, nil) != 1 { - return 0, newOpenSSLError("EVP_KDF_derive") + outLen := prevLen + needLen + if err := ossl.EVP_KDF_derive(c.ctx, base(c.buf), outLen, nil); err != nil { + return 0, err } n := copy(p, c.buf[prevLen:outLen]) return n, nil diff --git a/hmac.go b/hmac.go index b519ba31..22e9eec7 100644 --- a/hmac.go +++ b/hmac.go @@ -1,14 +1,14 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "hash" "runtime" "sync" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) // NewHMAC returns a new HMAC using OpenSSL. @@ -28,7 +28,7 @@ func NewHMAC(fh func() hash.Hash, key []byte) hash.Hash { // HMAC_Init will try and reuse the key from the ctx. This is // not the behavior previously implemented, so as a workaround // we pass an "empty" key. - key = make([]byte, C.GO_EVP_MAX_MD_SIZE) + key = make([]byte, ossl.EVP_MAX_MD_SIZE) } hmac := &opensslHMAC{ @@ -58,12 +58,12 @@ func NewHMAC(fh func() hash.Hash, key []byte) hash.Hash { // hmacCtx3 is used for OpenSSL 1. type hmacCtx1 struct { - ctx C.GO_HMAC_CTX_PTR + ctx ossl.HMAC_CTX_PTR } // hmacCtx3 is used for OpenSSL 3. type hmacCtx3 struct { - ctx C.GO_EVP_MAC_CTX_PTR + ctx ossl.EVP_MAC_CTX_PTR key []byte // only set for OpenSSL 3.0.0, 3.0.1, and 3.0.2. } @@ -75,64 +75,57 @@ type opensslHMAC struct { sum []byte } -func newHMAC1(key []byte, md C.GO_EVP_MD_PTR) hmacCtx1 { +func newHMAC1(key []byte, md ossl.EVP_MD_PTR) hmacCtx1 { ctx := hmacCtxNew() - if ctx == nil { - panic("openssl: EVP_MAC_CTX_new failed") - } - if C.go_openssl_HMAC_Init_ex(ctx, unsafe.Pointer(&key[0]), C.int(len(key)), md, nil) == 0 { - panic(newOpenSSLError("HMAC_Init_ex failed")) + if err := ossl.HMAC_Init_ex(ctx, unsafe.Pointer(&key[0]), int32(len(key)), md, nil); err != nil { + panic(err) } return hmacCtx1{ctx} } var hmacDigestsSupported sync.Map -var fetchHMAC3 = sync.OnceValue(func() C.GO_EVP_MAC_PTR { - name := C.CString("HMAC") - mac := C.go_openssl_EVP_MAC_fetch(nil, name, nil) - C.free(unsafe.Pointer(name)) - if mac == nil { +var fetchHMAC3 = sync.OnceValue(func() ossl.EVP_MAC_PTR { + mac, err := ossl.EVP_MAC_fetch(nil, cStringData(ossl.OSSL_MAC_NAME_HMAC), nil) + if err != nil { panic("openssl: HMAC not supported") } return mac }) -func buildHMAC3Params(digest *C.char) (C.GO_OSSL_PARAM_PTR, error) { +func buildHMAC3Params(digest *byte) (ossl.OSSL_PARAM_PTR, error) { bld, err := newParamBuilder() if err != nil { return nil, err } defer bld.finalize() - bld.addUTF8String(_OSSL_MAC_PARAM_DIGEST, digest, 0) + bld.addUTF8String(ossl.OSSL_MAC_PARAM_DIGEST, digest, 0) return bld.build() } -func isHMAC3DigestSupported(digest string) bool { +func isHMAC3DigestSupported(digest *byte) bool { if v, ok := hmacDigestsSupported.Load(digest); ok { return v.(bool) } - ctx := C.go_openssl_EVP_MAC_CTX_new(fetchHMAC3()) - if ctx == nil { - panic(newOpenSSLError("EVP_MAC_CTX_new")) + ctx, err := ossl.EVP_MAC_CTX_new(fetchHMAC3()) + if err != nil { + panic(err) } - defer C.go_openssl_EVP_MAC_CTX_free(ctx) + defer ossl.EVP_MAC_CTX_free(ctx) - cdigest := C.CString(digest) - defer C.free(unsafe.Pointer(cdigest)) - params, err := buildHMAC3Params(cdigest) + params, err := buildHMAC3Params(digest) if err != nil { panic(err) } - defer C.go_openssl_OSSL_PARAM_free(params) + defer ossl.OSSL_PARAM_free(params) - supported := C.go_openssl_EVP_MAC_CTX_set_params(ctx, params) != 0 + supported := ossl.EVP_MAC_CTX_set_params(ctx, params) != nil hmacDigestsSupported.Store(digest, supported) return supported } -func newHMAC3(key []byte, md C.GO_EVP_MD_PTR) hmacCtx3 { - digest := C.go_openssl_EVP_MD_get0_name(md) - if !isHMAC3DigestSupported(C.GoString(digest)) { +func newHMAC3(key []byte, md ossl.EVP_MD_PTR) hmacCtx3 { + digest := ossl.EVP_MD_get0_name(md) + if !isHMAC3DigestSupported(digest) { // The digest is not supported by the HMAC provider. // Don't panic here so the Go standard library to // fall back to the Go implementation. @@ -143,16 +136,16 @@ func newHMAC3(key []byte, md C.GO_EVP_MD_PTR) hmacCtx3 { if err != nil { panic(err) } - defer C.go_openssl_OSSL_PARAM_free(params) + defer ossl.OSSL_PARAM_free(params) - ctx := C.go_openssl_EVP_MAC_CTX_new(fetchHMAC3()) - if ctx == nil { - panic(newOpenSSLError("EVP_MAC_CTX_new")) + ctx, err := ossl.EVP_MAC_CTX_new(fetchHMAC3()) + if err != nil { + panic(err) } - if C.go_openssl_EVP_MAC_init(ctx, base(key), C.size_t(len(key)), params) == 0 { - C.go_openssl_EVP_MAC_CTX_free(ctx) - panic(newOpenSSLError("EVP_MAC_init")) + if err := ossl.EVP_MAC_init(ctx, base(key), len(key), params); err != nil { + ossl.EVP_MAC_CTX_free(ctx) + panic(err) } var hkey []byte if vMinor == 0 && vPatch <= 2 { @@ -170,12 +163,12 @@ func newHMAC3(key []byte, md C.GO_EVP_MD_PTR) hmacCtx3 { func (h *opensslHMAC) Reset() { switch vMajor { case 1: - if C.go_openssl_HMAC_Init_ex(h.ctx1.ctx, nil, 0, nil, nil) == 0 { - panic(newOpenSSLError("HMAC_Init_ex failed")) + if err := ossl.HMAC_Init_ex(h.ctx1.ctx, nil, 0, nil, nil); err != nil { + panic(err) } case 3: - if C.go_openssl_EVP_MAC_init(h.ctx3.ctx, base(h.ctx3.key), C.size_t(len(h.ctx3.key)), nil) == 0 { - panic(newOpenSSLError("EVP_MAC_init failed")) + if err := ossl.EVP_MAC_init(h.ctx3.ctx, base(h.ctx3.key), len(h.ctx3.key), nil); err != nil { + panic(err) } default: panic(errUnsupportedVersion()) @@ -190,7 +183,7 @@ func (h *opensslHMAC) finalize() { case 1: hmacCtxFree(h.ctx1.ctx) case 3: - C.go_openssl_EVP_MAC_CTX_free(h.ctx3.ctx) + ossl.EVP_MAC_CTX_free(h.ctx3.ctx) default: panic(errUnsupportedVersion()) } @@ -200,9 +193,9 @@ func (h *opensslHMAC) Write(p []byte) (int, error) { if len(p) > 0 { switch vMajor { case 1: - C.go_openssl_HMAC_Update(h.ctx1.ctx, base(p), C.size_t(len(p))) + ossl.HMAC_Update(h.ctx1.ctx, base(p), len(p)) case 3: - C.go_openssl_EVP_MAC_update(h.ctx3.ctx, base(p), C.size_t(len(p))) + ossl.EVP_MAC_update(h.ctx3.ctx, base(p), len(p)) default: panic(errUnsupportedVersion()) } @@ -231,44 +224,45 @@ func (h *opensslHMAC) Sum(in []byte) []byte { switch vMajor { case 1: ctx2 := hmacCtxNew() - if ctx2 == nil { - panic("openssl: HMAC_CTX_new failed") - } defer hmacCtxFree(ctx2) - if C.go_openssl_HMAC_CTX_copy(ctx2, h.ctx1.ctx) == 0 { - panic("openssl: HMAC_CTX_copy failed") + if err := ossl.HMAC_CTX_copy(ctx2, h.ctx1.ctx); err != nil { + panic(err) } - C.go_openssl_HMAC_Final(ctx2, base(h.sum), nil) + ossl.HMAC_Final(ctx2, base(h.sum), nil) case 3: - ctx2 := C.go_openssl_EVP_MAC_CTX_dup(h.ctx3.ctx) - if ctx2 == nil { - panic("openssl: EVP_MAC_CTX_dup failed") + ctx2, err := ossl.EVP_MAC_CTX_dup(h.ctx3.ctx) + if err != nil { + panic(err) } - defer C.go_openssl_EVP_MAC_CTX_free(ctx2) - C.go_openssl_EVP_MAC_final(ctx2, base(h.sum), nil, C.size_t(len(h.sum))) + defer ossl.EVP_MAC_CTX_free(ctx2) + ossl.EVP_MAC_final(ctx2, base(h.sum), nil, len(h.sum)) default: panic(errUnsupportedVersion()) } return append(in, h.sum...) } -func hmacCtxNew() C.GO_HMAC_CTX_PTR { +func hmacCtxNew() ossl.HMAC_CTX_PTR { if vMajor == 1 && vMinor == 0 { // 0x120 is the sizeof value when building against OpenSSL 1.0.2 on Ubuntu 16.04. - ctx := (C.GO_HMAC_CTX_PTR)(C.malloc(0x120)) + ctx := (ossl.HMAC_CTX_PTR)(ossl.CRYPTO_malloc_legacy102(0x120, nil, 0)) if ctx != nil { - C.go_openssl_HMAC_CTX_init(ctx) + ossl.HMAC_CTX_init(ctx) } return ctx } - return C.go_openssl_HMAC_CTX_new() + ctx, err := ossl.HMAC_CTX_new() + if err != nil { + panic(err) + } + return ctx } -func hmacCtxFree(ctx C.GO_HMAC_CTX_PTR) { +func hmacCtxFree(ctx ossl.HMAC_CTX_PTR) { if vMajor == 1 && vMinor == 0 { - C.go_openssl_HMAC_CTX_cleanup(ctx) - C.free(unsafe.Pointer(ctx)) + ossl.HMAC_CTX_cleanup(ctx) + ossl.CRYPTO_free_legacy102(unsafe.Pointer(ctx)) return } - C.go_openssl_HMAC_CTX_free(ctx) + ossl.HMAC_CTX_free(ctx) } diff --git a/init.go b/init.go index a1466329..9a2d0316 100644 --- a/init.go +++ b/init.go @@ -1,11 +1,11 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "errors" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) // opensslInit loads and initialize OpenSSL. @@ -24,9 +24,9 @@ func opensslInit(file string) (major, minor, patch uint, err error) { // Notice that major and minor could not match with the version parameter // in case the name of the shared library file differs from the OpenSSL // version it contains. - imajor := int(C.go_openssl_version_major(handle)) - iminor := int(C.go_openssl_version_minor(handle)) - ipatch := int(C.go_openssl_version_patch(handle)) + imajor := ossl.Go_openssl_version_major(handle) + iminor := ossl.Go_openssl_version_minor(handle) + ipatch := ossl.Go_openssl_version_minor(handle) if imajor < 0 || iminor < 0 || ipatch < 0 { return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") } @@ -42,22 +42,18 @@ func opensslInit(file string) (major, minor, patch uint, err error) { return 0, 0, 0, errUnsupportedVersion() } - // Load the OpenSSL functions. - // See shims.go for the complete list of supported functions. - C.go_openssl_load_functions(handle, C.uint(major), C.uint(minor), C.uint(patch)) + ossl.LoadLcrypto(handle) // Initialize OpenSSL. - C.go_openssl_OPENSSL_init() + ossl.OPENSSL_init() if major == 1 && minor == 0 { - if C.go_openssl_thread_setup() != 1 { - return 0, 0, 0, fail("openssl: thread setup") - } - C.go_openssl_OPENSSL_add_all_algorithms_conf() - C.go_openssl_ERR_load_crypto_strings() + ossl.ThreadSetup() + ossl.OPENSSL_add_all_algorithms_conf() + ossl.ERR_load_crypto_strings() } else { - flags := C.uint64_t(C.GO_OPENSSL_INIT_ADD_ALL_CIPHERS | C.GO_OPENSSL_INIT_ADD_ALL_DIGESTS | C.GO_OPENSSL_INIT_LOAD_CONFIG | C.GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS) - if C.go_openssl_OPENSSL_init_crypto(flags, nil) != 1 { - return 0, 0, 0, fail("openssl: init crypto") + flags := ossl.OPENSSL_INIT_ADD_ALL_CIPHERS | ossl.OPENSSL_INIT_ADD_ALL_DIGESTS | ossl.OPENSSL_INIT_LOAD_CONFIG | ossl.OPENSSL_INIT_LOAD_CRYPTO_STRINGS + if err := ossl.OPENSSL_init_crypto(uint64(flags), nil); err != nil { + return 0, 0, 0, err } } return major, minor, patch, nil diff --git a/leak_check.h b/leak_check.h new file mode 100644 index 00000000..ba3f8ad1 --- /dev/null +++ b/leak_check.h @@ -0,0 +1,13 @@ +static inline void +go_openssl_do_leak_check(void) +{ +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +#if (defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__) || \ + __has_feature(address_sanitizer) + extern void __lsan_do_leak_check(void); + __lsan_do_leak_check(); +#endif +} diff --git a/openssl.go b/openssl.go index 145b082f..feb589d7 100644 --- a/openssl.go +++ b/openssl.go @@ -1,9 +1,9 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo // Package openssl provides access to OpenSSL cryptographic functions. package openssl -// #include "goopenssl.h" +// #include "leak_check.h" import "C" import ( "encoding/binary" @@ -14,6 +14,8 @@ import ( "strings" "sync" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) var ( @@ -38,7 +40,7 @@ func CheckVersion(version string) (exists, fips bool) { return false, false } defer dlclose(handle) - enabled := C.go_openssl_fips_enabled(handle) + enabled := ossl.Go_openssl_fips_enabled(handle) fips = enabled == 1 // If go_openssl_fips_enabled returns -1, it means that all or some of the necessary // functions are not available. This can be due to the version of OpenSSL being too old, @@ -96,16 +98,17 @@ func (e fail) Error() string { return "openssl: " + string(e) + " failed" } // VersionText returns the version text of the OpenSSL currently loaded. func VersionText() string { - return C.GoString(C.go_openssl_OpenSSL_version(0)) + v := ossl.OpenSSL_version(0) + return goString(v) } -var ( - providerNameFips = C.CString("fips") - providerNameDefault = C.CString("default") - propFIPS = C.CString("fips=yes") - propNoFIPS = C.CString("-fips") +const ( + providerNameFips = "fips\x00" + providerNameDefault = "default\x00" + propFIPS = "fips=yes\x00" + propNoFIPS = "-fips\x00" - algorithmSHA256 = C.CString("SHA2-256") + algorithmSHA256 = "SHA2-256\x00" ) // FIPS returns true if OpenSSL is running in FIPS mode and there is @@ -113,10 +116,10 @@ var ( func FIPS() bool { switch vMajor { case 1: - return C.go_openssl_FIPS_mode() == 1 + return ossl.FIPS_mode() == 1 case 3: // Check if the default properties contain `fips=1`. - if C.go_openssl_EVP_default_properties_is_fips_enabled(nil) != 1 { + if ossl.EVP_default_properties_is_fips_enabled(nil) != 1 { // Note that it is still possible that the provider used by default is FIPS-compliant, // but that wouldn't be a system or user requirement. return false @@ -140,9 +143,7 @@ func isProviderAvailable(name string) bool { if vMajor == 1 { return false } - providerName := C.CString(name) - defer C.free(unsafe.Pointer(providerName)) - return C.go_openssl_OSSL_PROVIDER_available(nil, providerName) == 1 + return ossl.OSSL_PROVIDER_available(nil, cStringData(name)) == 1 } // SetFIPS enables or disables FIPS mode. @@ -154,20 +155,17 @@ func SetFIPS(enable bool) error { // Already in the desired state. return nil } - var mode C.int + var mode int32 if enable { - mode = C.int(1) + mode = 1 } else { - mode = C.int(0) + mode = 0 } switch vMajor { case 1: - if C.go_openssl_FIPS_mode_set(mode) != 1 { - return newOpenSSLError("FIPS_mode_set") - } - return nil + return ossl.FIPS_mode_set(mode) case 3: - var shaProps, provName *C.char + var shaProps, provName string if enable { shaProps = propFIPS provName = providerNameFips @@ -175,19 +173,16 @@ func SetFIPS(enable bool) error { shaProps = propNoFIPS provName = providerNameDefault } - if !proveSHA256(shaProps) { + if !proveSHA256(cStringData(shaProps)) { // There is no provider available that supports the desired FIPS mode. // Try to load the built-in provider associated with the given mode. - if C.go_openssl_OSSL_PROVIDER_try_load(nil, provName, 1) == nil { + if _, err := ossl.OSSL_PROVIDER_try_load(nil, cStringData(provName), 1); err != nil { // The built-in provider was not loaded successfully, we can't enable FIPS mode. - C.go_openssl_ERR_clear_error() + ossl.ERR_clear_error() return errors.New("openssl: FIPS mode not supported by any provider") } } - if C.go_openssl_EVP_default_properties_enable_fips(nil, mode) != 1 { - return newOpenSSLError("EVP_default_properties_enable_fips") - } - return nil + return ossl.EVP_default_properties_enable_fips(nil, mode) default: panic(errUnsupportedVersion()) } @@ -195,13 +190,13 @@ func SetFIPS(enable bool) error { // proveSHA256 checks if the SHA-256 algorithm is available // using the given properties. -func proveSHA256(props *C.char) bool { - md := C.go_openssl_EVP_MD_fetch(nil, algorithmSHA256, props) - if md == nil { - C.go_openssl_ERR_clear_error() +func proveSHA256(props *byte) bool { + md, err := ossl.EVP_MD_fetch(nil, cStringData(algorithmSHA256), props) + if err != nil { + ossl.ERR_clear_error() return false } - C.go_openssl_EVP_MD_free(md) + ossl.EVP_MD_free(md) return true } @@ -233,18 +228,27 @@ func addr(p []byte) *byte { // base returns the address of the underlying array in b, // being careful not to panic when b has zero length. -func base(b []byte) *C.uchar { - if len(b) == 0 { - return nil - } - return (*C.uchar)(unsafe.Pointer(&b[0])) +func base(b []byte) *byte { + return unsafe.SliceData(b) } -func sbase(b []byte) *C.char { - if len(b) == 0 { +// stringData returns a pointer to the underlying bytes of s. +// If s is not empty it must end in a NUL byte. +// The returned pointer is valid for the lifetime of s. +// If s is empty, stringData returns nil. +func cStringData(s string) *byte { + if len(s) == 0 { return nil } - return (*C.char)(unsafe.Pointer(&b[0])) + if s[len(s)-1] != 0 { + panic("openssl: stringData not NUL-terminated") + } + for i := 0; i < len(s)-1; i++ { + if s[i] == 0 { + panic("openssl: string contains non-trailing NUL byte") + } + } + return unsafe.StringData(s) } func newOpenSSLError(msg string) error { @@ -253,15 +257,15 @@ func newOpenSSLError(msg string) error { b.WriteString("\nopenssl error(s):") for { var ( - e C.ulong - file *C.char - line C.int + e uint64 + file *byte + line int32 ) switch vMajor { case 1: - e = C.go_openssl_ERR_get_error_line(&file, &line) + e = ossl.ERR_get_error_line(&file, &line) case 3: - e = C.go_openssl_ERR_get_error_all(&file, &line, nil, nil, nil) + e = ossl.ERR_get_error_all(&file, &line, nil, nil, nil) default: panic(errUnsupportedVersion()) } @@ -270,12 +274,26 @@ func newOpenSSLError(msg string) error { } b.WriteByte('\n') var buf [256]byte - C.go_openssl_ERR_error_string_n(e, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))) - b.WriteString(string(buf[:]) + "\n\t" + C.GoString(file) + ":" + strconv.Itoa(int(line))) + ossl.ERR_error_string_n(e, &buf[0], len(buf)) + b.WriteString(string(buf[:]) + "\n\t" + goString(file) + ":" + strconv.Itoa(int(line))) } return errors.New(b.String()) } +// goString converts a C null-terminated string to a Go string. +func goString(p *byte) string { + if p == nil { + return "" + } + end := unsafe.Pointer(p) + n := 0 + for *(*byte)(end) != 0 { + end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) + n++ + } + return string(unsafe.Slice(p, n)) +} + var unknownFile = "\000" // caller reports file and line number information about function invocations on @@ -284,7 +302,7 @@ var unknownFile = "\000" // the caller of caller. The return values report the file name and line number // within the file of the corresponding call. The returned file is a C string // with static storage duration. -func caller(skip int) (file *C.char, line C.int) { +func caller(skip int) (file *byte, line int32) { _, f, l, ok := runtime.Caller(skip + 1) if !ok { f = unknownFile @@ -292,9 +310,12 @@ func caller(skip int) (file *C.char, line C.int) { // The underlying bytes of the file string are null-terminated rodata with // static lifetimes, so can be safely passed to C without worrying about // leaking memory or use-after-free. - return (*C.char)(noescape(unsafe.Pointer(unsafe.StringData(f)))), C.int(l) + return (*byte)(noescape(unsafe.Pointer(unsafe.StringData(f)))), int32(l) } +//go:linkname runtime_throw runtime.throw +func runtime_throw(string) + // cryptoMalloc allocates n bytes of memory on the OpenSSL heap, which may be // different from the heap which C.malloc allocates on. The allocated object // must be freed using cryptoFree. cryptoMalloc is equivalent to the @@ -310,9 +331,9 @@ func cryptoMalloc(n int) unsafe.Pointer { file, line := caller(1) var p unsafe.Pointer if vMajor == 1 && vMinor == 0 { - p = C.go_openssl_CRYPTO_malloc_legacy102(C.int(n), file, line) + p = ossl.CRYPTO_malloc_legacy102(int32(n), file, line) } else { - p = C.go_openssl_CRYPTO_malloc(C.size_t(n), file, line) + p = ossl.CRYPTO_malloc(n, file, line) } if p == nil { // Un-recover()-ably crash the program in the same manner as the @@ -327,11 +348,11 @@ func cryptoMalloc(n int) unsafe.Pointer { // to the OPENSSL_free macro. func cryptoFree(p unsafe.Pointer) { if vMajor == 1 && vMinor == 0 { - C.go_openssl_CRYPTO_free_legacy102(p) + ossl.CRYPTO_free_legacy102(p) return } file, line := caller(1) - C.go_openssl_CRYPTO_free(p, file, line) + ossl.CRYPTO_free(p, file, line) } const wordBytes = bits.UintSize / 8 @@ -348,23 +369,23 @@ func (z BigInt) byteSwap() { } } -func wbase(b BigInt) *C.uchar { +func wbase(b BigInt) *byte { if len(b) == 0 { return nil } - return (*C.uchar)(unsafe.Pointer(&b[0])) + return (*byte)(unsafe.Pointer(&b[0])) } // bignum_st_1_0_2 is bignum_st (BIGNUM) memory layout in OpenSSL 1.0.2. type bignum_st_1_0_2 struct { d unsafe.Pointer // Pointer to an array of BN_ULONG bit chunks - top C.int // Index of last used d +1 - dmax C.int - neg C.int - flags C.int + top int32 // Index of last used d +1 + dmax int32 + neg int32 + flags int32 } -func bigToBN(x BigInt) C.GO_BIGNUM_PTR { +func bigToBN(x BigInt) ossl.BIGNUM_PTR { if len(x) == 0 { return nil } @@ -372,19 +393,19 @@ func bigToBN(x BigInt) C.GO_BIGNUM_PTR { if vMajor == 1 && vMinor == 0 { // OpenSSL 1.0.x does not export bn_lebin2bn on all platforms, // so we have to emulate it. - bn := C.go_openssl_BN_new() - if bn == nil { + bn, err := ossl.BN_new() + if err != nil { return nil } - if C.go_openssl_bn_expand2(bn, C.int(len(x))) == nil { - C.go_openssl_BN_free(bn) - panic(newOpenSSLError("BN_expand2")) + if _, err := ossl.BN_expand2(bn, int32(len(x))); err != nil { + ossl.BN_free(bn) + panic(err) } // The bytes of a BigInt are laid out in memory in the same order as a // BIGNUM, regardless of host endianness. bns := (*bignum_st_1_0_2)(unsafe.Pointer(bn)) d := unsafe.Slice((*uint)(bns.d), len(x)) - bns.top = C.int(copy(d, x)) + bns.top = int32(copy(d, x)) return bn } @@ -396,10 +417,11 @@ func bigToBN(x BigInt) C.GO_BIGNUM_PTR { } // Limbs are always ordered in LSB first, so we can safely apply // BN_lebin2bn regardless of host endianness. - return C.go_openssl_BN_lebin2bn(wbase(x), C.int(len(x)*wordBytes), nil) + bn, _ := ossl.BN_lebin2bn(wbase(x), int32(len(x)*wordBytes), nil) + return bn } -func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { +func bnToBig(bn ossl.BIGNUM_PTR) BigInt { if bn == nil { return nil } @@ -416,8 +438,8 @@ func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { // Limbs are always ordered in LSB first, so we can safely apply // BN_bn2lebinpad regardless of host endianness. - x := make(BigInt, C.go_openssl_BN_num_bits(bn)) - if C.go_openssl_BN_bn2lebinpad(bn, wbase(x), C.int(len(x)*wordBytes)) == 0 { + x := make(BigInt, ossl.BN_num_bits(bn)) + if _, err := ossl.BN_bn2lebinpad(bn, wbase(x), int32(len(x)*wordBytes)); err != nil { panic("openssl: bignum conversion failed") } if nativeEndian == binary.BigEndian { @@ -426,33 +448,33 @@ func bnToBig(bn C.GO_BIGNUM_PTR) BigInt { return x } -func bnNumBytes(bn C.GO_BIGNUM_PTR) int { - return (int(C.go_openssl_BN_num_bits(bn)) + 7) / 8 +func bnNumBytes(bn ossl.BIGNUM_PTR) int32 { + return (ossl.BN_num_bits(bn) + 7) / 8 } // bnToBinPad converts the absolute value of bn into big-endian form and stores // it at to, padding with zeroes if necessary. If len(to) is not large enough to // hold the result, an error is returned. -func bnToBinPad(bn C.GO_BIGNUM_PTR, to []byte) error { +func bnToBinPad(bn ossl.BIGNUM_PTR, to []byte) error { if vMajor == 1 && vMinor == 0 { // OpenSSL 1.0.x does not export bn_bn2binpad on all platforms, // so we have to emulate it. n := bnNumBytes(bn) - pad := len(to) - n + pad := int32(len(to)) - n if pad < 0 { return errors.New("openssl: destination buffer too small") } for i := range pad { to[i] = 0 } - if int(C.go_openssl_BN_bn2bin(bn, base(to[pad:]))) != n { + if ossl.BN_bn2bin(bn, base(to[pad:])) != n { return errors.New("openssl: BN_bn2bin short write") } return nil } - if C.go_openssl_BN_bn2binpad(bn, base(to), C.int(len(to))) < 0 { - return newOpenSSLError("BN_bn2binpad") + if _, err := ossl.BN_bn2binpad(bn, base(to), int32(len(to))); err != nil { + return err } return nil } diff --git a/params.go b/params.go index fa24a8cd..0c68079a 100644 --- a/params.go +++ b/params.go @@ -1,50 +1,17 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( + "errors" "runtime" "unsafe" -) -var ( - // KDF parameters - _OSSL_KDF_PARAM_DIGEST = C.CString("digest") - _OSSL_KDF_PARAM_SECRET = C.CString("secret") - _OSSL_KDF_PARAM_SEED = C.CString("seed") - _OSSL_KDF_PARAM_KEY = C.CString("key") - _OSSL_KDF_PARAM_INFO = C.CString("info") - _OSSL_KDF_PARAM_SALT = C.CString("salt") - _OSSL_KDF_PARAM_MODE = C.CString("mode") - - // PKEY parameters - _OSSL_PKEY_PARAM_PUB_KEY = C.CString("pub") - _OSSL_PKEY_PARAM_PRIV_KEY = C.CString("priv") - _OSSL_PKEY_PARAM_GROUP_NAME = C.CString("group") - _OSSL_PKEY_PARAM_EC_PUB_X = C.CString("qx") - _OSSL_PKEY_PARAM_EC_PUB_Y = C.CString("qy") - _OSSL_PKEY_PARAM_FFC_PBITS = C.CString("pbits") - _OSSL_PKEY_PARAM_FFC_QBITS = C.CString("qbits") - _OSSL_PKEY_PARAM_RSA_N = C.CString("n") - _OSSL_PKEY_PARAM_RSA_E = C.CString("e") - _OSSL_PKEY_PARAM_RSA_D = C.CString("d") - _OSSL_PKEY_PARAM_FFC_P = C.CString("p") - _OSSL_PKEY_PARAM_FFC_Q = C.CString("q") - _OSSL_PKEY_PARAM_FFC_G = C.CString("g") - _OSSL_PKEY_PARAM_RSA_FACTOR1 = C.CString("rsa-factor1") - _OSSL_PKEY_PARAM_RSA_FACTOR2 = C.CString("rsa-factor2") - _OSSL_PKEY_PARAM_RSA_EXPONENT1 = C.CString("rsa-exponent1") - _OSSL_PKEY_PARAM_RSA_EXPONENT2 = C.CString("rsa-exponent2") - _OSSL_PKEY_PARAM_RSA_COEFFICIENT1 = C.CString("rsa-coefficient1") - - // MAC parameters - _OSSL_MAC_PARAM_DIGEST = C.CString("digest") + "github.com/golang-fips/openssl/v2/internal/ossl" ) type bnParam struct { - value C.GO_BIGNUM_PTR + value ossl.BIGNUM_PTR private bool } @@ -53,7 +20,7 @@ type bnParam struct { // subsequent calls to add parameters are ignored // and build() will return the error. type paramBuilder struct { - bld C.GO_OSSL_PARAM_BLD_PTR + bld ossl.OSSL_PARAM_BLD_PTR pinner runtime.Pinner bnToFree []bnParam @@ -62,9 +29,9 @@ type paramBuilder struct { // newParamBuilder creates a new paramBuilder. func newParamBuilder() (*paramBuilder, error) { - bld := C.go_openssl_OSSL_PARAM_BLD_new() - if bld == nil { - return nil, newOpenSSLError("OSSL_PARAM_BLD_new") + bld, err := ossl.OSSL_PARAM_BLD_new() + if err != nil { + return nil, err } pb := ¶mBuilder{ bld: bld, @@ -80,12 +47,12 @@ func (b *paramBuilder) finalize() { b.pinner.Unpin() for _, bn := range b.bnToFree { if bn.private { - C.go_openssl_BN_clear_free(bn.value) + ossl.BN_clear_free(bn.value) } else { - C.go_openssl_BN_free(bn.value) + ossl.BN_free(bn.value) } } - C.go_openssl_OSSL_PARAM_BLD_free(b.bld) + ossl.OSSL_PARAM_BLD_free(b.bld) b.bld = nil } } @@ -109,69 +76,61 @@ func (b *paramBuilder) check() bool { // If an error occurred while adding parameters, the error is returned // and the OSSL_PARAM is nil. Once build() is called, the builder is finalized // and cannot be reused. -func (b *paramBuilder) build() (C.GO_OSSL_PARAM_PTR, error) { +func (b *paramBuilder) build() (ossl.OSSL_PARAM_PTR, error) { defer b.finalize() if !b.check() { return nil, b.err } - param := C.go_openssl_OSSL_PARAM_BLD_to_param(b.bld) - if param == nil { - return nil, newOpenSSLError("OSSL_PARAM_BLD_build") + param, err := ossl.OSSL_PARAM_BLD_to_param(b.bld) + if err != nil { + return nil, err } return param, nil } // addUTF8String adds a NUL-terminated UTF-8 string to the builder. // size should not include the terminating NUL byte. If size is zero, then it will be calculated. -func (b *paramBuilder) addUTF8String(name *C.char, value *C.char, size C.size_t) { +func (b *paramBuilder) addUTF8String(name string, value *byte, size int) { if !b.check() { return } // OSSL_PARAM_BLD_push_utf8_string calculates the size if it is zero. - if C.go_openssl_OSSL_PARAM_BLD_push_utf8_string(b.bld, name, value, size) != 1 { - b.err = newOpenSSLError("OSSL_PARAM_BLD_push_utf8_string(" + C.GoString(name) + ")") - } + b.err = ossl.OSSL_PARAM_BLD_push_utf8_string(b.bld, cStringData(name), value, size) } // addOctetString adds an octet string to the builder. // The value is pinned and will be unpinned when the builder is freed. -func (b *paramBuilder) addOctetString(name *C.char, value []byte) { +func (b *paramBuilder) addOctetString(name string, value []byte) { if !b.check() { return } if len(value) != 0 { b.pinner.Pin(&value[0]) } - if C.go_openssl_OSSL_PARAM_BLD_push_octet_string(b.bld, name, unsafe.Pointer(sbase(value)), C.size_t(len(value))) != 1 { - b.err = newOpenSSLError("OSSL_PARAM_BLD_push_octet_string(" + C.GoString(name) + ")") - } + b.err = ossl.OSSL_PARAM_BLD_push_octet_string(b.bld, cStringData(name), unsafe.Pointer(base(value)), len(value)) } // addInt32 adds an int32 to the builder. -func (b *paramBuilder) addInt32(name *C.char, value int32) { +func (b *paramBuilder) addInt32(name string, value int32) { if !b.check() { return } - if C.go_openssl_OSSL_PARAM_BLD_push_int32(b.bld, name, C.int32_t(value)) != 1 { - b.err = newOpenSSLError("OSSL_PARAM_BLD_push_int32(" + C.GoString(name) + ")") - } + b.err = ossl.OSSL_PARAM_BLD_push_int32(b.bld, cStringData(name), value) } // addBN adds a GO_BIGNUM_PTR to the builder. -func (b *paramBuilder) addBN(name *C.char, value C.GO_BIGNUM_PTR) { +func (b *paramBuilder) addBN(name string, value ossl.BIGNUM_PTR) { if !b.check() { return } - if C.go_openssl_OSSL_PARAM_BLD_push_BN(b.bld, name, value) != 1 { - b.err = newOpenSSLError("OSSL_PARAM_BLD_push_BN(" + C.GoString(name) + ")") - } + b.err = ossl.OSSL_PARAM_BLD_push_BN(b.bld, cStringData(name), value) } // addBin adds a byte slice to the builder. // The slice is converted to a BIGNUM using BN_bin2bn and freed when the builder is finalized. // If private is true, the BIGNUM will be cleared with BN_clear_free, // otherwise it will be freed with BN_free. -func (b *paramBuilder) addBin(name *C.char, value []byte, private bool) { +func (b *paramBuilder) addBin(name string, value []byte, private bool) { if !b.check() { return } @@ -179,9 +138,9 @@ func (b *paramBuilder) addBin(name *C.char, value []byte, private bool) { // Nothing to do. return } - bn := C.go_openssl_BN_bin2bn(base(value), C.int(len(value)), nil) - if bn == nil { - b.err = newOpenSSLError("BN_bin2bn") + bn, err := ossl.BN_bin2bn(base(value), int32(len(value)), nil) + if err != nil { + b.err = err return } b.bnToFree = append(b.bnToFree, bnParam{bn, private}) @@ -192,7 +151,7 @@ func (b *paramBuilder) addBin(name *C.char, value []byte, private bool) { // The BigInt is converted using bigToBN to a BIGNUM that is freed when the builder is finalized. // If private is true, the BIGNUM will be cleared with BN_clear_free, // otherwise it will be freed with BN_free. -func (b *paramBuilder) addBigInt(name *C.char, value BigInt, private bool) { +func (b *paramBuilder) addBigInt(name string, value BigInt, private bool) { if !b.check() { return } @@ -202,9 +161,13 @@ func (b *paramBuilder) addBigInt(name *C.char, value BigInt, private bool) { } bn := bigToBN(value) if bn == nil { - b.err = newOpenSSLError("bigToBN") + b.err = errors.New("bigToBN") return } b.bnToFree = append(b.bnToFree, bnParam{bn, private}) b.addBN(name, bn) } + +func getBnParam(pkey ossl.EVP_PKEY_PTR, name string, bn *ossl.BIGNUM_PTR) error { + return ossl.EVP_PKEY_get_bn_param(pkey, cStringData(name), bn) +} diff --git a/pbkdf2.go b/pbkdf2.go index 92276c6a..9599d675 100644 --- a/pbkdf2.go +++ b/pbkdf2.go @@ -1,14 +1,13 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "errors" "hash" "sync" - "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) // SupportsPBKDF2 reports whether the current OpenSSL version supports PBKDF2. @@ -27,14 +26,12 @@ func SupportsPBKDF2() bool { // fetchPBKDF2 fetches the PBKDF2 algorithm. // It is safe to call this function concurrently. // The returned EVP_KDF_PTR shouldn't be freed. -var fetchPBKDF2 = sync.OnceValues(func() (C.GO_EVP_KDF_PTR, error) { +var fetchPBKDF2 = sync.OnceValues(func() (ossl.EVP_KDF_PTR, error) { checkMajorVersion(3) - name := C.CString("PBKDF2") - kdf := C.go_openssl_EVP_KDF_fetch(nil, name, nil) - C.free(unsafe.Pointer(name)) - if kdf == nil { - return nil, newOpenSSLError("EVP_KDF_fetch") + kdf, err := ossl.EVP_KDF_fetch(nil, cStringData(ossl.OSSL_KDF_NAME_PBKDF2), nil) + if err != nil { + return nil, err } return kdf, nil }) @@ -51,12 +48,12 @@ func PBKDF2(password, salt []byte, iter, keyLen int, fh func() hash.Hash) ([]byt if len(password) == 0 && vMajor == 1 && vMinor == 0 { // x/crypto/pbkdf2 supports empty passwords, but OpenSSL 1.0.2 // does not. As a workaround, we pass an "empty" password. - password = make([]byte, C.GO_EVP_MAX_MD_SIZE) + password = make([]byte, ossl.EVP_MAX_MD_SIZE) } out := make([]byte, keyLen) - ok := C.go_openssl_PKCS5_PBKDF2_HMAC(sbase(password), C.int(len(password)), base(salt), C.int(len(salt)), C.int(iter), md, C.int(keyLen), base(out)) - if ok != 1 { - return nil, newOpenSSLError("PKCS5_PBKDF2_HMAC") + err = ossl.PKCS5_PBKDF2_HMAC(base(password), int32(len(password)), base(salt), int32(len(salt)), int32(iter), md, int32(keyLen), base(out)) + if err != nil { + return nil, err } return out, nil } diff --git a/rand.go b/rand.go index 9fd70963..073ed90d 100644 --- a/rand.go +++ b/rand.go @@ -1,18 +1,19 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" -import "unsafe" +import "github.com/golang-fips/openssl/v2/internal/ossl" type randReader int func (randReader) Read(b []byte) (int, error) { + if len(b) == 0 { + return 0, nil + } // Note: RAND_bytes should never fail; the return value exists only for historical reasons. // We check it even so. - if len(b) > 0 && C.go_openssl_RAND_bytes((*C.uchar)(unsafe.Pointer(&b[0])), C.int(len(b))) == 0 { - return 0, newOpenSSLError("RAND_bytes") + if err := ossl.RAND_bytes(&b[0], int32(len(b))); err != nil { + return 0, err } return len(b), nil } diff --git a/rc4.go b/rc4.go index f1cd3647..e75bc553 100644 --- a/rc4.go +++ b/rc4.go @@ -1,10 +1,13 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" -import "runtime" +import ( + "runtime" + "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" +) // SupportsRC4 returns true if NewRC4Cipher is supported. func SupportsRC4() bool { @@ -15,7 +18,7 @@ func SupportsRC4() bool { // A RC4Cipher is an instance of RC4 using a particular key. type RC4Cipher struct { - ctx C.GO_EVP_CIPHER_CTX_PTR + ctx ossl.EVP_CIPHER_CTX_PTR } // NewRC4Cipher creates and returns a new Cipher. @@ -31,14 +34,14 @@ func NewRC4Cipher(key []byte) (*RC4Cipher, error) { func (c *RC4Cipher) finalize() { if c.ctx != nil { - C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) + ossl.EVP_CIPHER_CTX_free(c.ctx) } } // Reset zeros the key data and makes the Cipher unusable. func (c *RC4Cipher) Reset() { if c.ctx != nil { - C.go_openssl_EVP_CIPHER_CTX_free(c.ctx) + ossl.EVP_CIPHER_CTX_free(c.ctx) c.ctx = nil } } @@ -55,9 +58,9 @@ func (c *RC4Cipher) XORKeyStream(dst, src []byte) { // panic if len(dst) < len(src) with a runtime out of bound error, // which is what crypto/rc4 does. _ = dst[len(src)-1] - var outLen C.int - if C.go_openssl_EVP_EncryptUpdate(c.ctx, base(dst), &outLen, base(src), C.int(len(src))) != 1 { - panic("crypto/cipher: EncryptUpdate failed") + var outLen int32 + if err := ossl.EVP_EncryptUpdate(c.ctx, unsafe.SliceData(dst), &outLen, unsafe.SliceData(src), int32(len(src))); err != nil { + panic(err) } if int(outLen) != len(src) { panic("crypto/rc4: src not fully XORed") diff --git a/rsa.go b/rsa.go index da5c7636..ec3b8a44 100644 --- a/rsa.go +++ b/rsa.go @@ -1,9 +1,7 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto" "crypto/subtle" @@ -11,65 +9,65 @@ import ( "hash" "runtime" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { bad := func(e error) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { return nil, nil, nil, nil, nil, nil, nil, nil, e } - pkey, err := generateEVPPKey(C.GO_EVP_PKEY_RSA, bits, "") + pkey, err := generateEVPPKey(ossl.EVP_PKEY_RSA, bits, "") if err != nil { return bad(err) } - defer C.go_openssl_EVP_PKEY_free(pkey) + defer ossl.EVP_PKEY_free(pkey) switch vMajor { case 1: - key := C.go_openssl_EVP_PKEY_get1_RSA(pkey) - if key == nil { + key, err := ossl.EVP_PKEY_get1_RSA(pkey) + if err != nil { return bad(newOpenSSLError("EVP_PKEY_get1_RSA failed")) } - defer C.go_openssl_RSA_free(key) - var n, e, d, p, q, dmp1, dmq1, iqmp C.GO_BIGNUM_PTR + defer ossl.RSA_free(key) + var n, e, d, p, q, dmp1, dmq1, iqmp ossl.BIGNUM_PTR if vMinor == 0 { r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) n, e, d, p, q, dmp1, dmq1, iqmp = r.n, r.e, r.d, r.p, r.q, r.dmp1, r.dmq1, r.iqmp } else { - C.go_openssl_RSA_get0_key(key, &n, &e, &d) - C.go_openssl_RSA_get0_factors(key, &p, &q) - C.go_openssl_RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp) + ossl.RSA_get0_key(key, &n, &e, &d) + ossl.RSA_get0_factors(key, &p, &q) + ossl.RSA_get0_crt_params(key, &dmp1, &dmq1, &iqmp) } N, E, D = bnToBig(n), bnToBig(e), bnToBig(d) P, Q = bnToBig(p), bnToBig(q) Dp, Dq, Qinv = bnToBig(dmp1), bnToBig(dmq1), bnToBig(iqmp) case 3: - tmp := C.go_openssl_BN_new() - if tmp == nil { - return bad(newOpenSSLError("BN_new failed")) + tmp, err := ossl.BN_new() + if err != nil { + return bad(err) } defer func() { - C.go_openssl_BN_clear_free(tmp) + ossl.BN_clear_free(tmp) }() - var err error - setBigInt := func(bi *BigInt, param *C.char) bool { + setBigInt := func(bi *BigInt, param string) bool { if err != nil { return false } - if C.go_openssl_EVP_PKEY_get_bn_param(pkey, param, &tmp) != 1 { - err = newOpenSSLError("EVP_PKEY_get_bn_param failed") + if err = getBnParam(pkey, param, &tmp); err != nil { return false } *bi = bnToBig(tmp) - C.go_openssl_BN_clear(tmp) + ossl.BN_clear(tmp) return true } - if !(setBigInt(&N, _OSSL_PKEY_PARAM_RSA_N) && - setBigInt(&E, _OSSL_PKEY_PARAM_RSA_E) && - setBigInt(&D, _OSSL_PKEY_PARAM_RSA_D) && - setBigInt(&P, _OSSL_PKEY_PARAM_RSA_FACTOR1) && - setBigInt(&Q, _OSSL_PKEY_PARAM_RSA_FACTOR2) && - setBigInt(&Dp, _OSSL_PKEY_PARAM_RSA_EXPONENT1) && - setBigInt(&Dq, _OSSL_PKEY_PARAM_RSA_EXPONENT2) && - setBigInt(&Qinv, _OSSL_PKEY_PARAM_RSA_COEFFICIENT1)) { + if !(setBigInt(&N, ossl.OSSL_PKEY_PARAM_RSA_N) && + setBigInt(&E, ossl.OSSL_PKEY_PARAM_RSA_E) && + setBigInt(&D, ossl.OSSL_PKEY_PARAM_RSA_D) && + setBigInt(&P, ossl.OSSL_PKEY_PARAM_RSA_FACTOR1) && + setBigInt(&Q, ossl.OSSL_PKEY_PARAM_RSA_FACTOR2) && + setBigInt(&Dp, ossl.OSSL_PKEY_PARAM_RSA_EXPONENT1) && + setBigInt(&Dq, ossl.OSSL_PKEY_PARAM_RSA_EXPONENT2) && + setBigInt(&Qinv, ossl.OSSL_PKEY_PARAM_RSA_COEFFICIENT1)) { return bad(err) } default: @@ -80,29 +78,29 @@ func GenerateKeyRSA(bits int) (N, E, D, P, Q, Dp, Dq, Qinv BigInt, err error) { type PublicKeyRSA struct { // _pkey MUST NOT be accessed directly. Instead, use the withKey method. - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func NewPublicKeyRSA(n, e BigInt) (*PublicKeyRSA, error) { - var pkey C.GO_EVP_PKEY_PTR + var pkey ossl.EVP_PKEY_PTR switch vMajor { case 1: - key := C.go_openssl_RSA_new() - if key == nil { - return nil, newOpenSSLError("RSA_new failed") + key, err := ossl.RSA_new() + if err != nil { + return nil, err } if !rsaSetKey(key, n, e, nil) { return nil, fail("RSA_set0_key") } - pkey = C.go_openssl_EVP_PKEY_new() - if pkey == nil { - C.go_openssl_RSA_free(key) - return nil, newOpenSSLError("EVP_PKEY_new failed") + pkey, err = ossl.EVP_PKEY_new() + if err != nil { + ossl.RSA_free(key) + return nil, err } - if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { - C.go_openssl_RSA_free(key) - C.go_openssl_EVP_PKEY_free(pkey) - return nil, newOpenSSLError("EVP_PKEY_assign failed") + if err := ossl.EVP_PKEY_assign(pkey, ossl.EVP_PKEY_RSA, (unsafe.Pointer)(key)); err != nil { + ossl.RSA_free(key) + ossl.EVP_PKEY_free(pkey) + return nil, err } case 3: var err error @@ -118,10 +116,10 @@ func NewPublicKeyRSA(n, e BigInt) (*PublicKeyRSA, error) { } func (k *PublicKeyRSA) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } -func (k *PublicKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { +func (k *PublicKeyRSA) withKey(f func(ossl.EVP_PKEY_PTR) error) error { // Because of the finalizer, any time _pkey is passed to cgo, that call must // be followed by a call to runtime.KeepAlive, to make sure k is not // collected (and finalized) before the cgo call returns. @@ -131,16 +129,16 @@ func (k *PublicKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { type PrivateKeyRSA struct { // _pkey MUST NOT be accessed directly. Instead, use the withKey method. - _pkey C.GO_EVP_PKEY_PTR + _pkey ossl.EVP_PKEY_PTR } func NewPrivateKeyRSA(n, e, d, p, q, dp, dq, qinv BigInt) (*PrivateKeyRSA, error) { - var pkey C.GO_EVP_PKEY_PTR + var pkey ossl.EVP_PKEY_PTR switch vMajor { case 1: - key := C.go_openssl_RSA_new() - if key == nil { - return nil, newOpenSSLError("RSA_new failed") + key, err := ossl.RSA_new() + if err != nil { + return nil, err } if !rsaSetKey(key, n, e, d) { return nil, fail("RSA_set0_key") @@ -155,15 +153,15 @@ func NewPrivateKeyRSA(n, e, d, p, q, dp, dq, qinv BigInt) (*PrivateKeyRSA, error return nil, fail("RSA_set0_crt_params") } } - pkey = C.go_openssl_EVP_PKEY_new() - if pkey == nil { - C.go_openssl_RSA_free(key) - return nil, newOpenSSLError("EVP_PKEY_new failed") + pkey, err = ossl.EVP_PKEY_new() + if err != nil { + ossl.RSA_free(key) + return nil, err } - if C.go_openssl_EVP_PKEY_assign(pkey, C.GO_EVP_PKEY_RSA, (unsafe.Pointer)(key)) != 1 { - C.go_openssl_RSA_free(key) - C.go_openssl_EVP_PKEY_free(pkey) - return nil, newOpenSSLError("EVP_PKEY_assign failed") + if err := ossl.EVP_PKEY_assign(pkey, ossl.EVP_PKEY_RSA, (unsafe.Pointer)(key)); err != nil { + ossl.RSA_free(key) + ossl.EVP_PKEY_free(pkey) + return nil, err } case 3: var err error @@ -179,10 +177,10 @@ func NewPrivateKeyRSA(n, e, d, p, q, dp, dq, qinv BigInt) (*PrivateKeyRSA, error } func (k *PrivateKeyRSA) finalize() { - C.go_openssl_EVP_PKEY_free(k._pkey) + ossl.EVP_PKEY_free(k._pkey) } -func (k *PrivateKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { +func (k *PrivateKeyRSA) withKey(f func(ossl.EVP_PKEY_PTR) error) error { // Because of the finalizer, any time _pkey is passed to cgo, that call must // be followed by a call to runtime.KeepAlive, to make sure k is not // collected (and finalized) before the cgo call returns. @@ -191,23 +189,23 @@ func (k *PrivateKeyRSA) withKey(f func(C.GO_EVP_PKEY_PTR) C.int) C.int { } func DecryptRSAOAEP(h, mgfHash hash.Hash, priv *PrivateKeyRSA, ciphertext, label []byte) ([]byte, error) { - return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, ciphertext) + return evpDecrypt(priv.withKey, ossl.RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, ciphertext) } func EncryptRSAOAEP(h, mgfHash hash.Hash, pub *PublicKeyRSA, msg, label []byte) ([]byte, error) { - return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, msg) + return evpEncrypt(pub.withKey, ossl.RSA_PKCS1_OAEP_PADDING, h, mgfHash, label, msg) } func DecryptRSAPKCS1(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { - return evpDecrypt(priv.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) + return evpDecrypt(priv.withKey, ossl.RSA_PKCS1_PADDING, nil, nil, nil, ciphertext) } func EncryptRSAPKCS1(pub *PublicKeyRSA, msg []byte) ([]byte, error) { - return evpEncrypt(pub.withKey, C.GO_RSA_PKCS1_PADDING, nil, nil, nil, msg) + return evpEncrypt(pub.withKey, ossl.RSA_PKCS1_PADDING, nil, nil, nil, msg) } func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) { - ret, err := evpDecrypt(priv.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, ciphertext) + ret, err := evpDecrypt(priv.withKey, ossl.RSA_NO_PADDING, nil, nil, nil, ciphertext) if err != nil { return nil, err } @@ -231,10 +229,10 @@ func DecryptRSANoPadding(priv *PrivateKeyRSA, ciphertext []byte) ([]byte, error) } func EncryptRSANoPadding(pub *PublicKeyRSA, msg []byte) ([]byte, error) { - return evpEncrypt(pub.withKey, C.GO_RSA_NO_PADDING, nil, nil, nil, msg) + return evpEncrypt(pub.withKey, ossl.RSA_NO_PADDING, nil, nil, nil, msg) } -func saltLength(saltLen int, sign bool) (C.int, error) { +func saltLength(saltLen int, sign bool) (int, error) { // A salt length of -2 is valid in OpenSSL, but not in crypto/rsa, so reject // it, and lengths < -2, before we convert to the OpenSSL sentinel values. if saltLen <= -2 { @@ -246,16 +244,16 @@ func saltLength(saltLen int, sign bool) (C.int, error) { if sign { if vMajor == 1 { // OpenSSL 1.x uses -2 to mean maximal size when signing where Go crypto uses 0. - return C.GO_RSA_PSS_SALTLEN_MAX_SIGN, nil + return ossl.RSA_PSS_SALTLEN_MAX_SIGN, nil } // OpenSSL 3.x deprecated RSA_PSS_SALTLEN_MAX_SIGN // and uses -3 to mean maximal size when signing where Go crypto uses 0. - return C.GO_RSA_PSS_SALTLEN_MAX, nil + return ossl.RSA_PSS_SALTLEN_MAX, nil } // OpenSSL uses -2 to mean auto-detect size when verifying where Go crypto uses 0. - return C.GO_RSA_PSS_SALTLEN_AUTO, nil + return ossl.RSA_PSS_SALTLEN_AUTO, nil } - return C.int(saltLen), nil + return saltLen, nil } func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) ([]byte, error) { @@ -263,7 +261,7 @@ func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) if err != nil { return nil, err } - return evpSign(priv.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, hashed) + return evpSign(priv.withKey, ossl.RSA_PKCS1_PSS_PADDING, cSaltLen, h, hashed) } func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen int) error { @@ -271,11 +269,11 @@ func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen if err != nil { return err } - return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PSS_PADDING, cSaltLen, h, sig, hashed) + return evpVerify(pub.withKey, ossl.RSA_PKCS1_PSS_PADDING, cSaltLen, h, sig, hashed) } func SignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte) ([]byte, error) { - return evpSign(priv.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, hashed) + return evpSign(priv.withKey, ossl.RSA_PKCS1_PADDING, 0, h, hashed) } func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte, error) { @@ -283,16 +281,16 @@ func HashSignRSAPKCS1v15(priv *PrivateKeyRSA, h crypto.Hash, msg []byte) ([]byte } func VerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte) error { - if pub.withKey(func(pkey C.GO_EVP_PKEY_PTR) C.int { - size := C.go_openssl_EVP_PKEY_get_size(pkey) + if err := pub.withKey(func(pkey ossl.EVP_PKEY_PTR) error { + size := ossl.EVP_PKEY_get_size(pkey) if len(sig) < int(size) { - return 0 + return errors.New("crypto/rsa: verification error") } - return 1 - }) == 0 { - return errors.New("crypto/rsa: verification error") + return nil + }); err != nil { + return err } - return evpVerify(pub.withKey, C.GO_RSA_PKCS1_PADDING, 0, h, sig, hashed) + return evpVerify(pub.withKey, ossl.RSA_PKCS1_PADDING, 0, h, sig, hashed) } func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) error { @@ -301,26 +299,26 @@ func HashVerifyRSAPKCS1v15(pub *PublicKeyRSA, h crypto.Hash, msg, sig []byte) er // rsa_st_1_0_2 is rsa_st memory layout in OpenSSL 1.0.2. type rsa_st_1_0_2 struct { - _ C.int - _ C.long + _ int32 + _ int64 _ [2]unsafe.Pointer - n, e, d C.GO_BIGNUM_PTR - p, q C.GO_BIGNUM_PTR - dmp1, dmq1, iqmp C.GO_BIGNUM_PTR + n, e, d ossl.BIGNUM_PTR + p, q ossl.BIGNUM_PTR + dmp1, dmq1, iqmp ossl.BIGNUM_PTR // It contains more fields, but we are not interesed on them. } -func bnSet(b1 *C.GO_BIGNUM_PTR, b2 BigInt) { +func bnSet(b1 *ossl.BIGNUM_PTR, b2 BigInt) { if b2 == nil { return } if *b1 != nil { - C.go_openssl_BN_clear_free(*b1) + ossl.BN_clear_free(*b1) } *b1 = bigToBN(b2) } -func rsaSetKey(key C.GO_RSA_PTR, n, e, d BigInt) bool { +func rsaSetKey(key ossl.RSA_PTR, n, e, d BigInt) bool { if vMajor == 1 && vMinor == 0 { r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) // r.d and d will be nil for public keys. @@ -333,10 +331,10 @@ func rsaSetKey(key C.GO_RSA_PTR, n, e, d BigInt) bool { bnSet(&r.d, d) return true } - return C.go_openssl_RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == 1 + return ossl.RSA_set0_key(key, bigToBN(n), bigToBN(e), bigToBN(d)) == nil } -func rsaSetFactors(key C.GO_RSA_PTR, p, q BigInt) bool { +func rsaSetFactors(key ossl.RSA_PTR, p, q BigInt) bool { if vMajor == 1 && vMinor == 0 { r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) if (r.p == nil && p == nil) || @@ -347,10 +345,10 @@ func rsaSetFactors(key C.GO_RSA_PTR, p, q BigInt) bool { bnSet(&r.q, q) return true } - return C.go_openssl_RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == 1 + return ossl.RSA_set0_factors(key, bigToBN(p), bigToBN(q)) == nil } -func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { +func rsaSetCRTParams(key ossl.RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { if vMajor == 1 && vMinor == 0 { r := (*rsa_st_1_0_2)(unsafe.Pointer(key)) if (r.dmp1 == nil && dmp1 == nil) || @@ -363,18 +361,18 @@ func rsaSetCRTParams(key C.GO_RSA_PTR, dmp1, dmq1, iqmp BigInt) bool { bnSet(&r.iqmp, iqmp) return true } - return C.go_openssl_RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == 1 + return ossl.RSA_set0_crt_params(key, bigToBN(dmp1), bigToBN(dmq1), bigToBN(iqmp)) == nil } -func newRSAKey3(isPriv bool, n, e, d, p, q, dp, dq, qinv BigInt) (C.GO_EVP_PKEY_PTR, error) { +func newRSAKey3(isPriv bool, n, e, d, p, q, dp, dq, qinv BigInt) (ossl.EVP_PKEY_PTR, error) { bld, err := newParamBuilder() if err != nil { return nil, err } defer bld.finalize() - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_N, n, false) - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_E, e, false) - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_D, d, false) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_N, n, false) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_E, e, false) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_D, d, false) if p != nil && q != nil { allPrecomputedExists := dp != nil && dq != nil && qinv != nil @@ -385,13 +383,13 @@ func newRSAKey3(isPriv bool, n, e, d, p, q, dp, dq, qinv BigInt) (C.GO_EVP_PKEY_ // In OpenSSL 3.0 and 3.1, we must also omit P and Q if any precomputed // value is missing. See https://github.com/openssl/openssl/pull/22334 if vMinor >= 2 || allPrecomputedExists { - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_FACTOR1, p, true) - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_FACTOR2, q, true) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_FACTOR1, p, true) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_FACTOR2, q, true) } if allPrecomputedExists { - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_EXPONENT1, dp, true) - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_EXPONENT2, dq, true) - bld.addBigInt(_OSSL_PKEY_PARAM_RSA_COEFFICIENT1, qinv, true) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_EXPONENT1, dp, true) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_EXPONENT2, dq, true) + bld.addBigInt(ossl.OSSL_PKEY_PARAM_RSA_COEFFICIENT1, qinv, true) } } @@ -399,10 +397,10 @@ func newRSAKey3(isPriv bool, n, e, d, p, q, dp, dq, qinv BigInt) (C.GO_EVP_PKEY_ if err != nil { return nil, err } - defer C.go_openssl_OSSL_PARAM_free(params) - selection := C.GO_EVP_PKEY_PUBLIC_KEY + defer ossl.OSSL_PARAM_free(params) + selection := ossl.EVP_PKEY_PUBLIC_KEY if isPriv { - selection = C.GO_EVP_PKEY_KEYPAIR + selection = ossl.EVP_PKEY_KEYPAIR } - return newEvpFromParams(C.GO_EVP_PKEY_RSA, C.int(selection), params) + return newEvpFromParams(ossl.EVP_PKEY_RSA, selection, params) } diff --git a/shims.h b/shims.h deleted file mode 100644 index 7d2e0a49..00000000 --- a/shims.h +++ /dev/null @@ -1,410 +0,0 @@ -#include // size_t -#include // uint64_t - -// #include -enum { - GO_OPENSSL_INIT_LOAD_CRYPTO_STRINGS = 0x00000002L, - GO_OPENSSL_INIT_ADD_ALL_CIPHERS = 0x00000004L, - GO_OPENSSL_INIT_ADD_ALL_DIGESTS = 0x00000008L, - GO_OPENSSL_INIT_LOAD_CONFIG = 0x00000040L -}; - -// #include -enum { - GO_EVP_CTRL_GCM_GET_TAG = 0x10, - GO_EVP_CTRL_GCM_SET_TAG = 0x11, - GO_EVP_PKEY_CTRL_MD = 1, - GO_EVP_PKEY_RSA = 6, - GO_EVP_PKEY_EC = 408, - GO_EVP_PKEY_TLS1_PRF = 1021, - GO_EVP_PKEY_HKDF = 1036, - GO_EVP_PKEY_ED25519 = 1087, - GO_EVP_PKEY_DSA = 116, - /* This is defined differently in OpenSSL 3 (1 << 11), but in our - * code it is only used in OpenSSL 1. - */ - GO1_EVP_PKEY_OP_DERIVE = (1 << 10), - GO_EVP_MAX_MD_SIZE = 64, - - GO_EVP_PKEY_PUBLIC_KEY = 0x86, - GO_EVP_PKEY_KEYPAIR = 0x87 -}; - -// #include -enum { - GO_EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID = 0x1001 -}; - -// #include -enum { - GO_EVP_KDF_HKDF_MODE_EXTRACT_ONLY = 1, - GO_EVP_KDF_HKDF_MODE_EXPAND_ONLY = 2, - - GO_EVP_PKEY_CTRL_TLS_MD = 0x1000, - GO_EVP_PKEY_CTRL_TLS_SECRET = 0x1001, - GO_EVP_PKEY_CTRL_TLS_SEED = 0x1002, - GO_EVP_PKEY_CTRL_HKDF_MD = 0x1003, - GO_EVP_PKEY_CTRL_HKDF_SALT = 0x1004, - GO_EVP_PKEY_CTRL_HKDF_KEY = 0x1005, - GO_EVP_PKEY_CTRL_HKDF_INFO = 0x1006, - GO_EVP_PKEY_CTRL_HKDF_MODE = 0x1007 -}; - -typedef enum { - GO_POINT_CONVERSION_UNCOMPRESSED = 4, -} point_conversion_form_t; - -// #include -enum { - GO_NID_X9_62_prime256v1 = 415, - GO_NID_secp224r1 = 713, - GO_NID_secp384r1 = 715, - GO_NID_secp521r1 = 716 -}; - -// #include -enum { - GO_RSA_PKCS1_PADDING = 1, - GO_RSA_NO_PADDING = 3, - GO_RSA_PKCS1_OAEP_PADDING = 4, - GO_RSA_PKCS1_PSS_PADDING = 6, - GO_RSA_PSS_SALTLEN_DIGEST = -1, - GO_RSA_PSS_SALTLEN_AUTO = -2, - GO_RSA_PSS_SALTLEN_MAX_SIGN = -2, - GO_RSA_PSS_SALTLEN_MAX = -3, - GO_EVP_PKEY_CTRL_RSA_PADDING = 0x1001, - GO_EVP_PKEY_CTRL_RSA_PSS_SALTLEN = 0x1002, - GO_EVP_PKEY_CTRL_RSA_KEYGEN_BITS = 0x1003, - GO_EVP_PKEY_CTRL_RSA_MGF1_MD = 0x1005, - GO_EVP_PKEY_CTRL_RSA_OAEP_MD = 0x1009, - GO_EVP_PKEY_CTRL_RSA_OAEP_LABEL = 0x100A, - GO_EVP_PKEY_CTRL_DSA_PARAMGEN_BITS = 0x1001, - GO_EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS = 0x1002 -}; - -typedef void* GO_OPENSSL_INIT_SETTINGS_PTR; -typedef void* GO_OSSL_LIB_CTX_PTR; -typedef void* GO_OSSL_PROVIDER_PTR; -typedef void* GO_ENGINE_PTR; -typedef void* GO_EVP_PKEY_PTR; -typedef void* GO_EVP_PKEY_CTX_PTR; -typedef void* GO_EVP_MD_PTR; -typedef void* GO_EVP_MD_CTX_PTR; -typedef void* GO_HMAC_CTX_PTR; -typedef void* GO_EVP_CIPHER_PTR; -typedef void* GO_EVP_CIPHER_CTX_PTR; -typedef void* GO_EC_KEY_PTR; -typedef void* GO_EC_POINT_PTR; -typedef void* GO_EC_GROUP_PTR; -typedef void* GO_RSA_PTR; -typedef void* GO_BIGNUM_PTR; -typedef void* GO_BN_CTX_PTR; -typedef void* GO_EVP_MAC_PTR; -typedef void* GO_EVP_MAC_CTX_PTR; -typedef void* GO_OSSL_PARAM_BLD_PTR; -typedef void* GO_OSSL_PARAM_PTR; -typedef void* GO_CRYPTO_THREADID_PTR; -typedef void* GO_EVP_SIGNATURE_PTR; -typedef void* GO_DSA_PTR; -typedef void* GO_EVP_KDF_PTR; -typedef void* GO_EVP_KDF_CTX_PTR; - -// #include -typedef void* GO_MD5_CTX_PTR; - -// #include -typedef void* GO_SHA_CTX_PTR; - -// FOR_ALL_OPENSSL_FUNCTIONS is the list of all functions from libcrypto that are used in this package. -// Forgetting to add a function here results in build failure with message reporting the function -// that needs to be added. -// -// The purpose of FOR_ALL_OPENSSL_FUNCTIONS is to define all libcrypto functions -// without depending on the openssl headers so it is easier to use this package -// with an openssl version different that the one used at build time. -// -// The following macros may not be defined at this point, -// they are not resolved here but just accumulated in FOR_ALL_OPENSSL_FUNCTIONS. -// -// DEFINEFUNC defines and loads openssl functions that can be directly called from Go as their signatures match -// the OpenSSL API and do not require special logic. -// The process will be aborted if the function can't be loaded. -// -// DEFINEFUNC_LEGACY_1_1 acts like DEFINEFUNC but only aborts the process if the function can't be loaded -// when using 1.1.x. This indicates the function is required when using 1.1.x, but is unused when using later versions. -// It also might not exist in later versions. -// -// DEFINEFUNC_LEGACY_1_0 acts like DEFINEFUNC but only aborts the process if the function can't be loaded -// when using 1.0.x. This indicates the function is required when using 1.0.x, but is unused when using later versions. -// It also might not exist in later versions. -// -// DEFINEFUNC_LEGACY_1 acts like DEFINEFUNC but only aborts the process if the function can't be loaded -// when using 1.x. This indicates the function is required when using 1.x, but is unused when using later versions. -// It also might not exist in later versions. -// -// DEFINEFUNC_1_1 acts like DEFINEFUNC but only aborts the process if function can't be loaded -// when using 1.1.0 or higher. -// -// DEFINEFUNC_1_1_1 acts like DEFINEFUNC but only aborts the process if function can't be loaded -// when using 1.1.1 or higher. -// -// DEFINEFUNC_3_0 acts like DEFINEFUNC but only aborts the process if function can't be loaded -// when using 3.0.0 or higher. -// -// DEFINEFUNC_RENAMED_1_1 acts like DEFINEFUNC but tries to load the function using the new name when using >= 1.1.x -// and the old name when using 1.0.2. In both cases the function will have the new name. -// -// DEFINEFUNC_RENAMED_3_0 acts like DEFINEFUNC but tries to load the function using the new name when using >= 3.x -// and the old name when using 1.x. In both cases the function will have the new name. -// -// DEFINEFUNC_VARIADIC_3_0 defines a function that wraps an OpenSSL function with a different name and signature. -// It should only be used for functions that can't be directly called from Go because their signature is not -// compatible with cgo. The only known case are functions that take a variable number of arguments. See -// https://github.com/golang/go/issues/975. -// The process is aborted if the function can't be loaded when using 3.0.0 or higher. -// -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #if OPENSSL_VERSION_NUMBER >= 0x30000000L -// #include -// #include -// #endif -// #if OPENSSL_VERSION_NUMBER < 0x10100000L -// #include -// #endif -#define FOR_ALL_OPENSSL_FUNCTIONS \ -DEFINEFUNC(void, ERR_error_string_n, (unsigned long e, char *buf, size_t len), (e, buf, len)) \ -DEFINEFUNC(void, ERR_clear_error, (void), ()) \ -DEFINEFUNC_LEGACY_1(unsigned long, ERR_get_error_line, (const char **file, int *line), (file, line)) \ -DEFINEFUNC_3_0(unsigned long, ERR_get_error_all, (const char **file, int *line, const char **func, const char **data, int *flags), (file, line, func, data, flags)) \ -DEFINEFUNC_RENAMED_1_1(const char *, OpenSSL_version, SSLeay_version, (int type), (type)) \ -DEFINEFUNC(void, OPENSSL_init, (void), ()) \ -DEFINEFUNC_LEGACY_1_0(void, ERR_load_crypto_strings, (void), ()) \ -DEFINEFUNC_LEGACY_1_0(void, ERR_remove_thread_state, (const GO_CRYPTO_THREADID_PTR tid), (tid)) \ -DEFINEFUNC_LEGACY_1_0(int, CRYPTO_num_locks, (void), ()) \ -DEFINEFUNC_LEGACY_1_0(int, CRYPTO_THREADID_set_callback, (void (*threadid_func) (GO_CRYPTO_THREADID_PTR)), (threadid_func)) \ -DEFINEFUNC_LEGACY_1_0(void, CRYPTO_THREADID_set_numeric, (GO_CRYPTO_THREADID_PTR id, unsigned long val), (id, val)) \ -DEFINEFUNC_LEGACY_1_0(void, CRYPTO_set_locking_callback, (void (*locking_function)(int mode, int n, const char *file, int line)), (locking_function)) \ -/* CRYPTO_malloc argument num changes from int to size_t in OpenSSL 1.1.0, */ \ -/* and CRYPTO_free has file and line arguments added. */ \ -/* Exclude them from headercheck tool when using previous OpenSSL versions. */ \ -/*check:from=1.1.0*/ DEFINEFUNC(void *, CRYPTO_malloc, (size_t num, const char *file, int line), (num, file, line)) \ -/*check:from=1.1.0*/ DEFINEFUNC(void, CRYPTO_free, (void *str, const char *file, int line), (str, file, line)) \ -DEFINEFUNC_LEGACY_1_0(void, OPENSSL_add_all_algorithms_conf, (void), ()) \ -DEFINEFUNC_1_1(int, OPENSSL_init_crypto, (uint64_t ops, const GO_OPENSSL_INIT_SETTINGS_PTR settings), (ops, settings)) \ -DEFINEFUNC_LEGACY_1(int, FIPS_mode, (void), ()) \ -DEFINEFUNC_LEGACY_1(int, FIPS_mode_set, (int r), (r)) \ -DEFINEFUNC_3_0(int, EVP_default_properties_is_fips_enabled, (GO_OSSL_LIB_CTX_PTR libctx), (libctx)) \ -DEFINEFUNC_3_0(int, EVP_default_properties_enable_fips, (GO_OSSL_LIB_CTX_PTR libctx, int enable), (libctx, enable)) \ -DEFINEFUNC_3_0(int, OSSL_PROVIDER_available, (GO_OSSL_LIB_CTX_PTR libctx, const char *name), (libctx, name)) \ -DEFINEFUNC_3_0(GO_OSSL_PROVIDER_PTR, OSSL_PROVIDER_try_load, (GO_OSSL_LIB_CTX_PTR libctx, const char *name, int retain_fallbacks), (libctx, name, retain_fallbacks)) \ -DEFINEFUNC_3_0(const char *, OSSL_PROVIDER_get0_name, (const GO_OSSL_PROVIDER_PTR prov), (prov)) \ -DEFINEFUNC_3_0(GO_EVP_MD_PTR, EVP_MD_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ -DEFINEFUNC_3_0(void, EVP_MD_free, (GO_EVP_MD_PTR md), (md)) \ -DEFINEFUNC_3_0(const char *, EVP_MD_get0_name, (const GO_EVP_MD_PTR md), (md)) \ -DEFINEFUNC_3_0(const GO_OSSL_PROVIDER_PTR, EVP_MD_get0_provider, (const GO_EVP_MD_PTR md), (md)) \ -DEFINEFUNC_RENAMED_3_0(int, EVP_MD_get_size, EVP_MD_size, (const GO_EVP_MD_PTR md), (md)) \ -DEFINEFUNC_RENAMED_3_0(int, EVP_MD_get_block_size, EVP_MD_block_size, (const GO_EVP_MD_PTR md), (md)) \ -DEFINEFUNC(int, RAND_bytes, (unsigned char *arg0, int arg1), (arg0, arg1)) \ -DEFINEFUNC_RENAMED_1_1(GO_EVP_MD_CTX_PTR, EVP_MD_CTX_new, EVP_MD_CTX_create, (void), ()) \ -DEFINEFUNC_RENAMED_1_1(void, EVP_MD_CTX_free, EVP_MD_CTX_destroy, (GO_EVP_MD_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC(int, EVP_MD_CTX_copy, (GO_EVP_MD_CTX_PTR out, const GO_EVP_MD_CTX_PTR in), (out, in)) \ -DEFINEFUNC(int, EVP_MD_CTX_copy_ex, (GO_EVP_MD_CTX_PTR out, const GO_EVP_MD_CTX_PTR in), (out, in)) \ -DEFINEFUNC(int, EVP_Digest, (const void *data, size_t count, unsigned char *md, unsigned int *size, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (data, count, md, size, type, impl)) \ -DEFINEFUNC(int, EVP_DigestInit_ex, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR impl), (ctx, type, impl)) \ -DEFINEFUNC(int, EVP_DigestInit, (GO_EVP_MD_CTX_PTR ctx, const GO_EVP_MD_PTR type), (ctx, type)) \ -DEFINEFUNC(int, EVP_DigestUpdate, (GO_EVP_MD_CTX_PTR ctx, const void *d, size_t cnt), (ctx, d, cnt)) \ -DEFINEFUNC(int, EVP_DigestFinal, (GO_EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s), (ctx, md, s)) \ -DEFINEFUNC_1_1_1(int, EVP_DigestSign, (GO_EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ -DEFINEFUNC(int, EVP_DigestSignInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ -DEFINEFUNC(int, EVP_DigestSignFinal, (GO_EVP_MD_CTX_PTR ctx, unsigned char *sig, size_t *siglen), (ctx, sig, siglen)) \ -DEFINEFUNC(int, EVP_DigestVerifyInit, (GO_EVP_MD_CTX_PTR ctx, GO_EVP_PKEY_CTX_PTR *pctx, const GO_EVP_MD_PTR type, GO_ENGINE_PTR e, GO_EVP_PKEY_PTR pkey), (ctx, pctx, type, e, pkey)) \ -DEFINEFUNC(int, EVP_DigestVerifyFinal, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen), (ctx, sig, siglen)) \ -DEFINEFUNC_1_1_1(int, EVP_DigestVerify, (GO_EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sigret, siglen, tbs, tbslen)) \ -DEFINEFUNC_LEGACY_1_0(int, MD5_Init, (GO_MD5_CTX_PTR c), (c)) \ -DEFINEFUNC_LEGACY_1_0(int, MD5_Update, (GO_MD5_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ -DEFINEFUNC_LEGACY_1_0(int, MD5_Final, (unsigned char *md, GO_MD5_CTX_PTR c), (md, c)) \ -DEFINEFUNC_LEGACY_1_0(int, SHA1_Init, (GO_SHA_CTX_PTR c), (c)) \ -DEFINEFUNC_LEGACY_1_0(int, SHA1_Update, (GO_SHA_CTX_PTR c, const void *data, size_t len), (c, data, len)) \ -DEFINEFUNC_LEGACY_1_0(int, SHA1_Final, (unsigned char *md, GO_SHA_CTX_PTR c), (md, c)) \ -DEFINEFUNC_1_1(const GO_EVP_MD_PTR, EVP_md5_sha1, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md4, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_md5, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha1, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha224, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha256, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha384, (void), ()) \ -DEFINEFUNC(const GO_EVP_MD_PTR, EVP_sha512, (void), ()) \ -DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_224, (void), ()) \ -DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_256, (void), ()) \ -DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_384, (void), ()) \ -DEFINEFUNC_1_1_1(const GO_EVP_MD_PTR, EVP_sha3_512, (void), ()) \ -DEFINEFUNC_LEGACY_1_0(void, HMAC_CTX_init, (GO_HMAC_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1_0(void, HMAC_CTX_cleanup, (GO_HMAC_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(int, HMAC_Init_ex, (GO_HMAC_CTX_PTR arg0, const void *arg1, int arg2, const GO_EVP_MD_PTR arg3, GO_ENGINE_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ -DEFINEFUNC_LEGACY_1(int, HMAC_Update, (GO_HMAC_CTX_PTR arg0, const unsigned char *arg1, size_t arg2), (arg0, arg1, arg2)) \ -DEFINEFUNC_LEGACY_1(int, HMAC_Final, (GO_HMAC_CTX_PTR arg0, unsigned char *arg1, unsigned int *arg2), (arg0, arg1, arg2)) \ -DEFINEFUNC_LEGACY_1(int, HMAC_CTX_copy, (GO_HMAC_CTX_PTR dest, GO_HMAC_CTX_PTR src), (dest, src)) \ -DEFINEFUNC_LEGACY_1_1(void, HMAC_CTX_free, (GO_HMAC_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1_1(GO_HMAC_CTX_PTR, HMAC_CTX_new, (void), ()) \ -DEFINEFUNC(GO_EVP_CIPHER_CTX_PTR, EVP_CIPHER_CTX_new, (void), ()) \ -DEFINEFUNC(int, EVP_CIPHER_CTX_set_padding, (GO_EVP_CIPHER_CTX_PTR x, int padding), (x, padding)) \ -DEFINEFUNC(int, EVP_CipherInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv, int enc), (ctx, type, impl, key, iv, enc)) \ -DEFINEFUNC(int, EVP_CipherUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ -DEFINEFUNC(int, EVP_EncryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ -DEFINEFUNC(int, EVP_EncryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ -DEFINEFUNC(int, EVP_EncryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl), (ctx, out, outl)) \ -DEFINEFUNC(int, EVP_DecryptInit_ex, (GO_EVP_CIPHER_CTX_PTR ctx, const GO_EVP_CIPHER_PTR type, GO_ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv), (ctx, type, impl, key, iv)) \ -DEFINEFUNC(int, EVP_DecryptUpdate, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl), (ctx, out, outl, in, inl)) \ -DEFINEFUNC(int, EVP_DecryptFinal_ex, (GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl), (ctx, outm, outl)) \ -DEFINEFUNC_3_0(GO_EVP_CIPHER_PTR, EVP_CIPHER_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ -DEFINEFUNC_3_0(const char *, EVP_CIPHER_get0_name, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_gcm, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_cbc, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_ctr, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_128_ecb, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_gcm, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_cbc, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_ctr, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_192_ecb, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_cbc, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ctr, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_ecb, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_aes_256_gcm, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ecb, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_cbc, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_ecb, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_des_ede3_cbc, (void), ()) \ -DEFINEFUNC(const GO_EVP_CIPHER_PTR, EVP_rc4, (void), ()) \ -DEFINEFUNC_RENAMED_3_0(int, EVP_CIPHER_get_block_size, EVP_CIPHER_block_size, (const GO_EVP_CIPHER_PTR cipher), (cipher)) \ -DEFINEFUNC(int, EVP_CIPHER_CTX_set_key_length, (GO_EVP_CIPHER_CTX_PTR x, int keylen), (x, keylen)) \ -DEFINEFUNC(void, EVP_CIPHER_CTX_free, (GO_EVP_CIPHER_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EVP_CIPHER_CTX_ctrl, (GO_EVP_CIPHER_CTX_PTR ctx, int type, int arg, void *ptr), (ctx, type, arg, ptr)) \ -DEFINEFUNC(GO_EVP_PKEY_PTR, EVP_PKEY_new, (void), ()) \ -DEFINEFUNC_1_1_1(GO_EVP_PKEY_PTR, EVP_PKEY_new_raw_private_key, (int type, GO_ENGINE_PTR e, const unsigned char *key, size_t keylen), (type, e, key, keylen)) \ -DEFINEFUNC_1_1_1(GO_EVP_PKEY_PTR, EVP_PKEY_new_raw_public_key, (int type, GO_ENGINE_PTR e, const unsigned char *key, size_t keylen), (type, e, key, keylen)) \ -/* EVP_PKEY_size and EVP_PKEY_get_bits pkey parameter is const since OpenSSL 1.1.1. */ \ -/* Exclude it from headercheck tool when using previous OpenSSL versions. */ \ -/*check:from=1.1.1*/ DEFINEFUNC_RENAMED_3_0(int, EVP_PKEY_get_size, EVP_PKEY_size, (const GO_EVP_PKEY_PTR pkey), (pkey)) \ -/*check:from=1.1.1*/ DEFINEFUNC_RENAMED_3_0(int, EVP_PKEY_get_bits, EVP_PKEY_bits, (const GO_EVP_PKEY_PTR pkey), (pkey)) \ -DEFINEFUNC(void, EVP_PKEY_free, (GO_EVP_PKEY_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(GO_RSA_PTR, EVP_PKEY_get1_RSA, (GO_EVP_PKEY_PTR pkey), (pkey)) \ -DEFINEFUNC_LEGACY_1(int, EVP_PKEY_assign, (GO_EVP_PKEY_PTR pkey, int type, void *key), (pkey, type, key)) \ -DEFINEFUNC(int, EVP_PKEY_verify, (GO_EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen), (ctx, sig, siglen, tbs, tbslen)) \ -DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new, (GO_EVP_PKEY_PTR arg0, GO_ENGINE_PTR arg1), (arg0, arg1)) \ -DEFINEFUNC(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new_id, (int id, GO_ENGINE_PTR e), (id, e)) \ -DEFINEFUNC_3_0(GO_EVP_PKEY_CTX_PTR, EVP_PKEY_CTX_new_from_pkey, (GO_OSSL_LIB_CTX_PTR libctx, GO_EVP_PKEY_PTR pkey, const char *propquery), (libctx, pkey, propquery)) \ -DEFINEFUNC(int, EVP_PKEY_paramgen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC(int, EVP_PKEY_paramgen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ -DEFINEFUNC(int, EVP_PKEY_keygen_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC(int, EVP_PKEY_keygen, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *ppkey), (ctx, ppkey)) \ -DEFINEFUNC_VARIADIC_3_0(GO_EVP_PKEY_PTR, EVP_PKEY_Q_keygen, EVP_PKEY_Q_keygen, (GO_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type), (ctx, propq, type)) \ -DEFINEFUNC_VARIADIC_3_0(GO_EVP_PKEY_PTR, EVP_PKEY_Q_keygen, EVP_PKEY_Q_keygen_RSA, (GO_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type, size_t arg1), (ctx, propq, type, arg1)) \ -DEFINEFUNC_VARIADIC_3_0(GO_EVP_PKEY_PTR, EVP_PKEY_Q_keygen, EVP_PKEY_Q_keygen_EC, (GO_OSSL_LIB_CTX_PTR ctx, const char *propq, const char *type, const char *arg1), (ctx, propq, type, arg1)) \ -DEFINEFUNC(void, EVP_PKEY_CTX_free, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EVP_PKEY_CTX_ctrl, (GO_EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2), (ctx, keytype, optype, cmd, p1, p2)) \ -DEFINEFUNC(int, EVP_PKEY_decrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ -DEFINEFUNC(int, EVP_PKEY_encrypt, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ -DEFINEFUNC(int, EVP_PKEY_decrypt_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EVP_PKEY_encrypt_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EVP_PKEY_sign_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EVP_PKEY_verify_init, (GO_EVP_PKEY_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EVP_PKEY_sign, (GO_EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4), (arg0, arg1, arg2, arg3, arg4)) \ -DEFINEFUNC(int, EVP_PKEY_derive_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC(int, EVP_PKEY_derive_set_peer, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR peer), (ctx, peer)) \ -DEFINEFUNC(int, EVP_PKEY_derive, (GO_EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t *keylen), (ctx, key, keylen)) \ -DEFINEFUNC_LEGACY_1_0(void*, EVP_PKEY_get0, (GO_EVP_PKEY_PTR pkey), (pkey)) \ -DEFINEFUNC_LEGACY_1_1(GO_EC_KEY_PTR, EVP_PKEY_get0_EC_KEY, (GO_EVP_PKEY_PTR pkey), (pkey)) \ -DEFINEFUNC_LEGACY_1_1(GO_DSA_PTR, EVP_PKEY_get0_DSA, (GO_EVP_PKEY_PTR pkey), (pkey)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_fromdata_init, (GO_EVP_PKEY_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_fromdata, (GO_EVP_PKEY_CTX_PTR ctx, GO_EVP_PKEY_PTR *pkey, int selection, GO_OSSL_PARAM_PTR params), (ctx, pkey, selection, params)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_set1_encoded_public_key, (GO_EVP_PKEY_PTR pkey, const unsigned char *pub, size_t publen), (pkey, pub, publen)) \ -DEFINEFUNC_3_0(size_t, EVP_PKEY_get1_encoded_public_key, (GO_EVP_PKEY_PTR pkey, unsigned char **ppub), (pkey, ppub)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_get_bn_param, (const GO_EVP_PKEY_PTR pkey, const char *key_name, GO_BIGNUM_PTR *bn), (pkey, key_name, bn)) \ -DEFINEFUNC_LEGACY_1(GO_RSA_PTR, RSA_new, (void), ()) \ -DEFINEFUNC_LEGACY_1(void, RSA_free, (GO_RSA_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1_1(int, RSA_set0_factors, (GO_RSA_PTR rsa, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q), (rsa, p, q)) \ -DEFINEFUNC_LEGACY_1_1(int, RSA_set0_crt_params, (GO_RSA_PTR rsa, GO_BIGNUM_PTR dmp1, GO_BIGNUM_PTR dmp2, GO_BIGNUM_PTR iqmp), (rsa, dmp1, dmp2, iqmp)) \ -DEFINEFUNC_LEGACY_1_1(void, RSA_get0_crt_params, (const GO_RSA_PTR r, const GO_BIGNUM_PTR *dmp1, const GO_BIGNUM_PTR *dmq1, const GO_BIGNUM_PTR *iqmp), (r, dmp1, dmq1, iqmp)) \ -DEFINEFUNC_LEGACY_1_1(int, RSA_set0_key, (GO_RSA_PTR r, GO_BIGNUM_PTR n, GO_BIGNUM_PTR e, GO_BIGNUM_PTR d), (r, n, e, d)) \ -DEFINEFUNC_LEGACY_1_1(void, RSA_get0_factors, (const GO_RSA_PTR rsa, const GO_BIGNUM_PTR *p, const GO_BIGNUM_PTR *q), (rsa, p, q)) \ -DEFINEFUNC_LEGACY_1_1(void, RSA_get0_key, (const GO_RSA_PTR rsa, const GO_BIGNUM_PTR *n, const GO_BIGNUM_PTR *e, const GO_BIGNUM_PTR *d), (rsa, n, e, d)) \ -DEFINEFUNC(GO_BIGNUM_PTR, BN_new, (void), ()) \ -DEFINEFUNC(void, BN_free, (GO_BIGNUM_PTR arg0), (arg0)) \ -DEFINEFUNC(void, BN_clear, (GO_BIGNUM_PTR arg0), (arg0)) \ -DEFINEFUNC(void, BN_clear_free, (GO_BIGNUM_PTR arg0), (arg0)) \ -DEFINEFUNC(int, BN_num_bits, (const GO_BIGNUM_PTR arg0), (arg0)) \ -DEFINEFUNC(GO_BIGNUM_PTR, BN_bin2bn, (const unsigned char *arg0, int arg1, GO_BIGNUM_PTR arg2), (arg0, arg1, arg2)) \ -DEFINEFUNC_LEGACY_1_0(int, BN_bn2bin, (const GO_BIGNUM_PTR a, unsigned char *to), (a, to)) \ -DEFINEFUNC_LEGACY_1_0(GO_BIGNUM_PTR, bn_expand2, (GO_BIGNUM_PTR a, int n), (a, n)) \ -DEFINEFUNC_1_1(GO_BIGNUM_PTR, BN_lebin2bn, (const unsigned char *s, int len, GO_BIGNUM_PTR ret), (s, len, ret)) \ -DEFINEFUNC_1_1(int, BN_bn2lebinpad, (const GO_BIGNUM_PTR a, unsigned char *to, int tolen), (a, to, tolen)) \ -DEFINEFUNC_1_1(int, BN_bn2binpad, (const GO_BIGNUM_PTR a, unsigned char *to, int tolen), (a, to, tolen)) \ -DEFINEFUNC_LEGACY_1(int, EC_KEY_set_public_key_affine_coordinates, (GO_EC_KEY_PTR key, GO_BIGNUM_PTR x, GO_BIGNUM_PTR y), (key, x, y)) \ -DEFINEFUNC_LEGACY_1(int, EC_KEY_set_public_key, (GO_EC_KEY_PTR key, const GO_EC_POINT_PTR pub), (key, pub)) \ -DEFINEFUNC_LEGACY_1(void, EC_KEY_free, (GO_EC_KEY_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(const GO_EC_GROUP_PTR, EC_KEY_get0_group, (const GO_EC_KEY_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(const GO_BIGNUM_PTR, EC_KEY_get0_private_key, (const GO_EC_KEY_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(const GO_EC_POINT_PTR, EC_KEY_get0_public_key, (const GO_EC_KEY_PTR arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(GO_EC_KEY_PTR, EC_KEY_new_by_curve_name, (int arg0), (arg0)) \ -DEFINEFUNC_LEGACY_1(int, EC_KEY_set_private_key, (GO_EC_KEY_PTR arg0, const GO_BIGNUM_PTR arg1), (arg0, arg1)) \ -DEFINEFUNC(GO_EC_POINT_PTR, EC_POINT_new, (const GO_EC_GROUP_PTR arg0), (arg0)) \ -DEFINEFUNC(void, EC_POINT_free, (GO_EC_POINT_PTR arg0), (arg0)) \ -DEFINEFUNC(int, EC_POINT_mul, (const GO_EC_GROUP_PTR group, GO_EC_POINT_PTR r, const GO_BIGNUM_PTR n, const GO_EC_POINT_PTR q, const GO_BIGNUM_PTR m, GO_BN_CTX_PTR ctx), (group, r, n, q, m, ctx)) \ -DEFINEFUNC_LEGACY_1(int, EC_POINT_get_affine_coordinates_GFp, (const GO_EC_GROUP_PTR arg0, const GO_EC_POINT_PTR arg1, GO_BIGNUM_PTR arg2, GO_BIGNUM_PTR arg3, GO_BN_CTX_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ -DEFINEFUNC_3_0(int, EC_POINT_set_affine_coordinates, (const GO_EC_GROUP_PTR arg0, GO_EC_POINT_PTR arg1, const GO_BIGNUM_PTR arg2, const GO_BIGNUM_PTR arg3, GO_BN_CTX_PTR arg4), (arg0, arg1, arg2, arg3, arg4)) \ -DEFINEFUNC(size_t, EC_POINT_point2oct, (const GO_EC_GROUP_PTR group, const GO_EC_POINT_PTR p, point_conversion_form_t form, unsigned char *buf, size_t len, GO_BN_CTX_PTR ctx), (group, p, form, buf, len, ctx)) \ -DEFINEFUNC(int, EC_POINT_oct2point, (const GO_EC_GROUP_PTR group, GO_EC_POINT_PTR p, const unsigned char *buf, size_t len, GO_BN_CTX_PTR ctx), (group, p, buf, len, ctx)) \ -DEFINEFUNC(const char *, OBJ_nid2sn, (int n), (n)) \ -DEFINEFUNC(GO_EC_GROUP_PTR, EC_GROUP_new_by_curve_name, (int nid), (nid)) \ -DEFINEFUNC(void, EC_GROUP_free, (GO_EC_GROUP_PTR group), (group)) \ -DEFINEFUNC_3_0(GO_EVP_MAC_PTR, EVP_MAC_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ -DEFINEFUNC_3_0(GO_EVP_MAC_CTX_PTR, EVP_MAC_CTX_new, (GO_EVP_MAC_PTR arg0), (arg0)) \ -DEFINEFUNC_3_0(int, EVP_MAC_CTX_set_params, (GO_EVP_MAC_CTX_PTR ctx, const GO_OSSL_PARAM_PTR params), (ctx, params)) \ -DEFINEFUNC_3_0(void, EVP_MAC_CTX_free, (GO_EVP_MAC_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC_3_0(GO_EVP_MAC_CTX_PTR, EVP_MAC_CTX_dup, (const GO_EVP_MAC_CTX_PTR arg0), (arg0)) \ -DEFINEFUNC_3_0(int, EVP_MAC_init, (GO_EVP_MAC_CTX_PTR ctx, const unsigned char *key, size_t keylen, const GO_OSSL_PARAM_PTR params), (ctx, key, keylen, params)) \ -DEFINEFUNC_3_0(int, EVP_MAC_update, (GO_EVP_MAC_CTX_PTR ctx, const unsigned char *data, size_t datalen), (ctx, data, datalen)) \ -DEFINEFUNC_3_0(int, EVP_MAC_final, (GO_EVP_MAC_CTX_PTR ctx, unsigned char *out, size_t *outl, size_t outsize), (ctx, out, outl, outsize)) \ -DEFINEFUNC_3_0(void, OSSL_PARAM_free, (GO_OSSL_PARAM_PTR p), (p)) \ -DEFINEFUNC_3_0(GO_OSSL_PARAM_BLD_PTR, OSSL_PARAM_BLD_new, (void), ()) \ -DEFINEFUNC_3_0(void, OSSL_PARAM_BLD_free, (GO_OSSL_PARAM_BLD_PTR bld), (bld)) \ -DEFINEFUNC_3_0(GO_OSSL_PARAM_PTR, OSSL_PARAM_BLD_to_param, (GO_OSSL_PARAM_BLD_PTR bld), (bld)) \ -DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_utf8_string, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, const char *buf, size_t bsize), (bld, key, buf, bsize)) \ -DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_octet_string, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, const void *buf, size_t bsize), (bld, key, buf, bsize)) \ -DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_BN, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, const GO_BIGNUM_PTR bn), (bld, key, bn)) \ -DEFINEFUNC_3_0(int, OSSL_PARAM_BLD_push_int32, (GO_OSSL_PARAM_BLD_PTR bld, const char *key, int32_t num), (bld, key, num)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_hkdf_mode, (GO_EVP_PKEY_CTX_PTR arg0, int arg1), (arg0, arg1)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set_hkdf_md, (GO_EVP_PKEY_CTX_PTR arg0, const GO_EVP_MD_PTR arg1), (arg0, arg1)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_hkdf_salt, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set1_hkdf_key, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_CTX_add1_hkdf_info, (GO_EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2), (arg0, arg1, arg2)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_up_ref, (GO_EVP_PKEY_PTR key), (key)) \ -DEFINEFUNC_LEGACY_1(int, EVP_PKEY_set1_EC_KEY, (GO_EVP_PKEY_PTR pkey, GO_EC_KEY_PTR key), (pkey, key)) \ -DEFINEFUNC_3_0(int, EVP_PKEY_CTX_set0_rsa_oaep_label, (GO_EVP_PKEY_CTX_PTR ctx, void *label, int len), (ctx, label, len)) \ -DEFINEFUNC(int, PKCS5_PBKDF2_HMAC, (const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const GO_EVP_MD_PTR digest, int keylen, unsigned char *out), (pass, passlen, salt, saltlen, iter, digest, keylen, out)) \ -DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_public_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len), (pkey, pub, len)) \ -DEFINEFUNC_1_1_1(int, EVP_PKEY_get_raw_private_key, (const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len), (pkey, priv, len)) \ -DEFINEFUNC_3_0(GO_EVP_SIGNATURE_PTR, EVP_SIGNATURE_fetch, (GO_OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties), (ctx, algorithm, properties)) \ -DEFINEFUNC_3_0(void, EVP_SIGNATURE_free, (GO_EVP_SIGNATURE_PTR signature), (signature)) \ -DEFINEFUNC_LEGACY_1(GO_DSA_PTR, DSA_new, (void), ()) \ -DEFINEFUNC_LEGACY_1(void, DSA_free, (GO_DSA_PTR r), (r)) \ -DEFINEFUNC_LEGACY_1(int, DSA_generate_key, (GO_DSA_PTR a), (a)) \ -DEFINEFUNC_LEGACY_1_1(void, DSA_get0_pqg, (const GO_DSA_PTR d, const GO_BIGNUM_PTR *p, const GO_BIGNUM_PTR *q, const GO_BIGNUM_PTR *g), (d, p, q, g)) \ -DEFINEFUNC_LEGACY_1_1(int, DSA_set0_pqg, (GO_DSA_PTR d, GO_BIGNUM_PTR p, GO_BIGNUM_PTR q, GO_BIGNUM_PTR g), (d, p, q, g)) \ -DEFINEFUNC_LEGACY_1_1(void, DSA_get0_key, (const GO_DSA_PTR d, const GO_BIGNUM_PTR *pub_key, const GO_BIGNUM_PTR *priv_key), (d, pub_key, priv_key)) \ -DEFINEFUNC_LEGACY_1_1(int, DSA_set0_key, (GO_DSA_PTR d, GO_BIGNUM_PTR pub_key, GO_BIGNUM_PTR priv_key), (d, pub_key, priv_key)) \ -DEFINEFUNC_3_0(GO_EVP_KDF_PTR, EVP_KDF_fetch, (GO_OSSL_LIB_CTX_PTR libctx, const char *algorithm, const char *properties), (libctx, algorithm, properties)) \ -DEFINEFUNC_3_0(void, EVP_KDF_free, (GO_EVP_KDF_PTR kdf), (kdf)) \ -DEFINEFUNC_3_0(GO_EVP_KDF_CTX_PTR, EVP_KDF_CTX_new, (GO_EVP_KDF_PTR kdf), (kdf)) \ -DEFINEFUNC_3_0(int, EVP_KDF_CTX_set_params, (GO_EVP_KDF_CTX_PTR ctx, const GO_OSSL_PARAM_PTR params), (ctx, params)) \ -DEFINEFUNC_3_0(void, EVP_KDF_CTX_free, (GO_EVP_KDF_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC_3_0(size_t, EVP_KDF_CTX_get_kdf_size, (GO_EVP_KDF_CTX_PTR ctx), (ctx)) \ -DEFINEFUNC_3_0(int, EVP_KDF_derive, (GO_EVP_KDF_CTX_PTR ctx, unsigned char *key, size_t keylen, const GO_OSSL_PARAM_PTR params), (ctx, key, keylen, params)) \ - diff --git a/tls1prf.go b/tls1prf.go index f342f221..34c27284 100644 --- a/tls1prf.go +++ b/tls1prf.go @@ -1,15 +1,15 @@ -//go:build !cmd_go_bootstrap +//go:build !cmd_go_bootstrap && cgo package openssl -// #include "goopenssl.h" -import "C" import ( "crypto" "errors" "hash" "sync" "unsafe" + + "github.com/golang-fips/openssl/v2/internal/ossl" ) func SupportsTLS1PRF() bool { @@ -28,7 +28,7 @@ func SupportsTLS1PRF() bool { // else it implements the TLS 1.2 pseudo-random function. // The pseudo-random number will be written to result and will be of length len(result). func TLS1PRF(result, secret, label, seed []byte, fh func() hash.Hash) error { - var md C.GO_EVP_MD_PTR + var md ossl.EVP_MD_PTR if fh == nil { // TLS 1.0/1.1 PRF doesn't allow to specify the hash function, // it always uses MD5SHA1. If h is nil, then assume @@ -58,53 +58,53 @@ func TLS1PRF(result, secret, label, seed []byte, fh func() hash.Hash) error { } // tls1PRF1 implements TLS1PRF for OpenSSL 1 using the EVP_PKEY API. -func tls1PRF1(result, secret, label, seed []byte, md C.GO_EVP_MD_PTR) error { +func tls1PRF1(result, secret, label, seed []byte, md ossl.EVP_MD_PTR) error { checkMajorVersion(1) - ctx := C.go_openssl_EVP_PKEY_CTX_new_id(C.GO_EVP_PKEY_TLS1_PRF, nil) - if ctx == nil { - return newOpenSSLError("EVP_PKEY_CTX_new_id") + ctx, err := ossl.EVP_PKEY_CTX_new_id(ossl.EVP_PKEY_TLS1_PRF, nil) + if err != nil { + return err } defer func() { - C.go_openssl_EVP_PKEY_CTX_free(ctx) + ossl.EVP_PKEY_CTX_free(ctx) }() - if C.go_openssl_EVP_PKEY_derive_init(ctx) != 1 { - return newOpenSSLError("EVP_PKEY_derive_init") - } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, - C.GO1_EVP_PKEY_OP_DERIVE, - C.GO_EVP_PKEY_CTRL_TLS_MD, - 0, unsafe.Pointer(md)) != 1 { - return newOpenSSLError("EVP_PKEY_CTX_set_tls1_prf_md") - } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, - C.GO1_EVP_PKEY_OP_DERIVE, - C.GO_EVP_PKEY_CTRL_TLS_SECRET, - C.int(len(secret)), unsafe.Pointer(base(secret))) != 1 { - return newOpenSSLError("EVP_PKEY_CTX_set1_tls1_prf_secret") - } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, - C.GO1_EVP_PKEY_OP_DERIVE, - C.GO_EVP_PKEY_CTRL_TLS_SEED, - C.int(len(label)), unsafe.Pointer(base(label))) != 1 { - return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") - } - if C.go_openssl_EVP_PKEY_CTX_ctrl(ctx, -1, - C.GO1_EVP_PKEY_OP_DERIVE, - C.GO_EVP_PKEY_CTRL_TLS_SEED, - C.int(len(seed)), unsafe.Pointer(base(seed))) != 1 { - return newOpenSSLError("EVP_PKEY_CTX_add1_tls1_prf_seed") - } - outLen := C.size_t(len(result)) - if C.go_openssl_EVP_PKEY_derive_wrapper(ctx, base(result), outLen).result != 1 { - return newOpenSSLError("EVP_PKEY_derive") + if err := ossl.EVP_PKEY_derive_init(ctx); err != nil { + return err + } + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, + ossl.GO1_EVP_PKEY_OP_DERIVE, + ossl.EVP_PKEY_CTRL_TLS_MD, + 0, unsafe.Pointer(md)); err != nil { + return err + } + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, + ossl.GO1_EVP_PKEY_OP_DERIVE, + ossl.EVP_PKEY_CTRL_TLS_SECRET, + int32(len(secret)), unsafe.Pointer(base(secret))); err != nil { + return err + } + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, + ossl.GO1_EVP_PKEY_OP_DERIVE, + ossl.EVP_PKEY_CTRL_TLS_SEED, + int32(len(label)), unsafe.Pointer(base(label))); err != nil { + return err + } + if err := ossl.EVP_PKEY_CTX_ctrl(ctx, -1, + ossl.GO1_EVP_PKEY_OP_DERIVE, + ossl.EVP_PKEY_CTRL_TLS_SEED, + int32(len(seed)), unsafe.Pointer(base(seed))); err != nil { + return err + } + outLen := len(result) + if outLen, err = ossl.EVP_PKEY_derive_wrapper(ctx, base(result), outLen); err != nil { + return err } // The Go standard library expects TLS1PRF to return the requested number of bytes, // fail if it doesn't. While there is no known situation where this will happen, // EVP_PKEY_derive handles multiple algorithms and there could be a subtle mismatch // after more code changes in the future. - if outLen != C.size_t(len(result)) { + if outLen != len(result) { return errors.New("tls1-prf: derived less bytes than requested") } return nil @@ -113,48 +113,43 @@ func tls1PRF1(result, secret, label, seed []byte, md C.GO_EVP_MD_PTR) error { // fetchTLS1PRF3 fetches the TLS1-PRF KDF algorithm. // It is safe to call this function concurrently. // The returned EVP_KDF_PTR shouldn't be freed. -var fetchTLS1PRF3 = sync.OnceValues(func() (C.GO_EVP_KDF_PTR, error) { +var fetchTLS1PRF3 = sync.OnceValues(func() (ossl.EVP_KDF_PTR, error) { checkMajorVersion(3) - name := C.CString("TLS1-PRF") - kdf := C.go_openssl_EVP_KDF_fetch(nil, name, nil) - C.free(unsafe.Pointer(name)) - if kdf == nil { - return nil, newOpenSSLError("EVP_KDF_fetch") + kdf, err := ossl.EVP_KDF_fetch(nil, cStringData(ossl.OSSL_KDF_NAME_TLS1_PRF), nil) + if err != nil { + return nil, err } return kdf, nil }) // tls1PRF3 implements TLS1PRF for OpenSSL 3 using the EVP_KDF API. -func tls1PRF3(result, secret, label, seed []byte, md C.GO_EVP_MD_PTR) error { +func tls1PRF3(result, secret, label, seed []byte, md ossl.EVP_MD_PTR) error { checkMajorVersion(3) kdf, err := fetchTLS1PRF3() if err != nil { return err } - ctx := C.go_openssl_EVP_KDF_CTX_new(kdf) - if ctx == nil { - return newOpenSSLError("EVP_KDF_CTX_new") + ctx, err := ossl.EVP_KDF_CTX_new(kdf) + if err != nil { + return err } - defer C.go_openssl_EVP_KDF_CTX_free(ctx) + defer ossl.EVP_KDF_CTX_free(ctx) bld, err := newParamBuilder() if err != nil { return err } - bld.addUTF8String(_OSSL_KDF_PARAM_DIGEST, C.go_openssl_EVP_MD_get0_name(md), 0) - bld.addOctetString(_OSSL_KDF_PARAM_SECRET, secret) - bld.addOctetString(_OSSL_KDF_PARAM_SEED, label) - bld.addOctetString(_OSSL_KDF_PARAM_SEED, seed) + bld.addUTF8String(ossl.OSSL_KDF_PARAM_DIGEST, ossl.EVP_MD_get0_name(md), 0) + bld.addOctetString(ossl.OSSL_KDF_PARAM_SECRET, secret) + bld.addOctetString(ossl.OSSL_KDF_PARAM_SEED, label) + bld.addOctetString(ossl.OSSL_KDF_PARAM_SEED, seed) params, err := bld.build() if err != nil { return err } - defer C.go_openssl_OSSL_PARAM_free(params) + defer ossl.OSSL_PARAM_free(params) - if C.go_openssl_EVP_KDF_derive(ctx, base(result), C.size_t(len(result)), params) != 1 { - return newOpenSSLError("EVP_KDF_derive") - } - return nil + return ossl.EVP_KDF_derive(ctx, base(result), len(result), params) } From 93ea06463c86af207b1ce973cdaf2663a3b3c9e1 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 12:55:16 +0100 Subject: [PATCH 07/20] fix err != err --- dsa.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dsa.go b/dsa.go index 73a2cd76..53a01ec0 100644 --- a/dsa.go +++ b/dsa.go @@ -102,13 +102,13 @@ func GenerateDSAParameters(l, n int) (DSAParameters, error) { ossl.BN_free(q) ossl.BN_free(g) }() - if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_P, &p); err != err { + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_P, &p); err != nil { return DSAParameters{}, err } - if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_Q, &q); err != err { + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_Q, &q); err != nil { return DSAParameters{}, err } - if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_G, &g); err != err { + if err := getBnParam(pkey, ossl.OSSL_PKEY_PARAM_FFC_G, &g); err != nil { return DSAParameters{}, err } default: From 84e939af819d5516702ee2a85641945bcd5e5828 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 14:20:13 +0100 Subject: [PATCH 08/20] skip checkheader --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6c213bcc..5268a4ef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,9 +19,9 @@ jobs: uses: actions/checkout@v4 - name: Install OpenSSL 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 + #- name: Check headers + # working-directory: ./cmd/checkheader + # run: go run . --ossl-include /usr/local/src/openssl-${{ matrix.openssl-version }}/include -shim ../../shims.h - name: Set OpenSSL config and prove FIPS run: | sudo cp ./scripts/openssl-3.cnf /usr/local/ssl/openssl.cnf From 8387637f274fa7c69404c1e32443a982cedef242 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 14:28:48 +0100 Subject: [PATCH 09/20] fix headers --- internal/ossl/api.h | 1 + internal/ossl/ossl_extra.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ossl/api.h b/internal/ossl/api.h index e96919a0..828b6064 100644 --- a/internal/ossl/api.h +++ b/internal/ossl/api.h @@ -2,6 +2,7 @@ #include "ossl.h" #include +#include void ERR_clear_error(void); void ERR_error_string_n(unsigned long e, char *buf, size_t len); diff --git a/internal/ossl/ossl_extra.h b/internal/ossl/ossl_extra.h index dd1be420..e44234a2 100644 --- a/internal/ossl/ossl_extra.h +++ b/internal/ossl/ossl_extra.h @@ -1,5 +1,4 @@ #include "api.h" -#include int go_openssl_fips_enabled(void* handle); int go_openssl_version_major(void* handle); From 0d5cf990a532783870a59a0ecbb8774227c77c14 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 14:32:18 +0100 Subject: [PATCH 10/20] remove unnecessary code --- internal/mkcgo/generate.go | 1 - internal/mkcgo/mkcgo.go | 4 ---- 2 files changed, 5 deletions(-) diff --git a/internal/mkcgo/generate.go b/internal/mkcgo/generate.go index 3030d813..2c79ba38 100644 --- a/internal/mkcgo/generate.go +++ b/internal/mkcgo/generate.go @@ -275,7 +275,6 @@ func (r *rets) useLongHandleErrorCode(retvar, msg string) string { if strings.HasSuffix(r.typ, "*") || strings.HasSuffix(strings.ToUpper(r.typ), "_PTR") { cond = retvar + " == nil" } else { - cond = retvar + " != " + defaultErrorCodeStr cond = strings.Replace(r.failCond, "retval", retvar, 1) } return fmt.Sprintf(code, cond, msg) diff --git a/internal/mkcgo/mkcgo.go b/internal/mkcgo/mkcgo.go index 8d91cbd2..403846f8 100644 --- a/internal/mkcgo/mkcgo.go +++ b/internal/mkcgo/mkcgo.go @@ -10,10 +10,6 @@ import ( "strings" ) -var ( - defaultErrorCodeStr string -) - var ( fileName = flag.String("out", "", "output file name (standard output if omitted)") includeHeader = flag.String("include", "", "include header file") From 1e75ee30ef43d10fe9ab5bcf2af6f5861531e08f Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 14:55:48 +0100 Subject: [PATCH 11/20] fix attributes --- internal/mkcgo/mkcgo.go | 2 +- internal/mkcgo/parse.go | 107 ++++++++------ internal/ossl/api.h | 316 ++++++++++++++++++++-------------------- 3 files changed, 224 insertions(+), 201 deletions(-) diff --git a/internal/mkcgo/mkcgo.go b/internal/mkcgo/mkcgo.go index 403846f8..63abb765 100644 --- a/internal/mkcgo/mkcgo.go +++ b/internal/mkcgo/mkcgo.go @@ -89,7 +89,7 @@ type rets struct { fnMaybeAbsent bool } -type fnOptions struct { +type fnAttributes struct { name string libName string errorType string diff --git a/internal/mkcgo/parse.go b/internal/mkcgo/parse.go index eb46d1eb..5c4f4510 100644 --- a/internal/mkcgo/parse.go +++ b/internal/mkcgo/parse.go @@ -36,11 +36,11 @@ func (src *source) parseFile(name string) error { defer file.Close() s := bufio.NewScanner(file) var inComment bool - var srcOps, fnOps fnOptions + var srcOps, fnOps fnAttributes var t string for s.Scan() { line := trim(s.Text()) - if strings.HasPrefix(line, "/*") { + if strings.HasPrefix(line, "/*") && !strings.HasPrefix(line, "/*[[mkcgo::") { if !strings.HasSuffix(line, "*/") { inComment = true } @@ -61,47 +61,20 @@ func (src *source) parseFile(name string) error { } return errors.New("Unknown mkcgo directive: " + t) } - - if strings.HasPrefix(line, "[[") { - for { - var body string - var ok bool - _, body, line, ok = extractSection(line, "[[", "]]") - if !ok { - break - } - body, ok = strings.CutPrefix(body, "mkcgo::") - if !ok { - continue - } - if body == "error" { - fnOps.returnsError = true - } else if body == "error_only" { - fnOps.returnsError = true - fnOps.errorOnly = true - } else if body == "c_only" { - fnOps.cOnly = true - } else if strings.HasPrefix(body, "error(") || strings.HasPrefix(body, "error_only(") { - fnOps.returnsError = true - fnOps.errorOnly = strings.HasPrefix(body, "error_only(") - if _, body, _, ok = extractSection(body, "(", ")"); ok { - fnOps.failCondition = strings.Trim(body, `"`) - } - } else if strings.HasPrefix(body, "name(") { - if _, body, _, ok = extractSection(body, "(", ")"); ok { - fnOps.name = strings.Trim(body, `"`) - } - } else if strings.HasPrefix(body, "variadic(") { - if _, body, _, ok = extractSection(body, "(", ")"); ok { - fnOps.importName = strings.Trim(body, `"`) - } - } - } - } - if strings.HasPrefix(line, "//") || strings.HasPrefix(line, "#") { continue } + if strings.HasPrefix(line, "/*[[mkcgo:") { + end := strings.LastIndex(line, "*/") + if end == -1 { + return errors.New("Could not find closing attributes comment in \"" + line + "\"") + } + err = extractFunctionAttributes(line[2:end], &fnOps) + if err != nil { + return err + } + line = line[end+2:] + } if line == "" { continue } @@ -118,7 +91,7 @@ func (src *source) parseFile(name string) error { return err } src.funcs = append(src.funcs, f) - fnOps = fnOptions{ + fnOps = fnAttributes{ errorType: srcOps.errorType, failCondition: srcOps.failCondition, } @@ -134,7 +107,7 @@ func (src *source) parseFile(name string) error { } // newFn parses string s and return created function Fn. -func newFn(s string, opts fnOptions) (*fn, error) { +func newFn(s string, opts fnAttributes) (*fn, error) { f := &fn{ rets: &rets{}, src: s, @@ -208,6 +181,56 @@ func extractSection(s string, start, end string) (prefix, body, suffix string, f return prefix, a[0], a[1], true } +func extractFunctionAttributes(s string, attrs *fnAttributes) error { + s = trim(s) + if s == "" { + return nil + } + for { + var body string + var ok bool + _, body, s, ok = extractSection(s, "[[", "]]") + if !ok { + break + } + body, ok = strings.CutPrefix(body, "mkcgo::") + if !ok { + return errors.New("Could not extract mkcgo attribute from \"" + body + "\"") + } + if body == "error" { + attrs.returnsError = true + } else if body == "error_only" { + attrs.returnsError = true + attrs.errorOnly = true + } else if body == "c_only" { + attrs.cOnly = true + } else if strings.HasPrefix(body, "error(") || strings.HasPrefix(body, "error_only(") { + attrs.returnsError = true + attrs.errorOnly = strings.HasPrefix(body, "error_only(") + if _, body, _, ok = extractSection(body, "(", ")"); ok { + attrs.failCondition = strings.Trim(body, `"`) + } else { + return errors.New("Could not extract error attribute value") + } + } else if strings.HasPrefix(body, "name(") { + if _, body, _, ok = extractSection(body, "(", ")"); ok { + attrs.name = strings.Trim(body, `"`) + } else { + return errors.New("Could not extract name attribute value") + } + } else if strings.HasPrefix(body, "variadic(") { + if _, body, _, ok = extractSection(body, "(", ")"); ok { + attrs.importName = strings.Trim(body, `"`) + } else { + return errors.New("Could not extract variadic attribute value") + } + } else { + return errors.New("Unknown mkcgo attribute: " + body) + } + } + return nil +} + // extractParams parses s to extract function parameters. func extractParams(s string) ([]*param, error) { s = trim(s) diff --git a/internal/ossl/api.h b/internal/ossl/api.h index 828b6064..b673a770 100644 --- a/internal/ossl/api.h +++ b/internal/ossl/api.h @@ -11,29 +11,29 @@ unsigned long ERR_get_error_all(const char **file, int *line, const char **fn, const char **data, int *flags); void ERR_load_crypto_strings(void); -[[mkcgo::c_only]] void ERR_remove_thread_state(const CRYPTO_THREADID_PTR tid); +/*[[mkcgo::c_only]]*/ void ERR_remove_thread_state(const CRYPTO_THREADID_PTR tid); -[[mkcgo::c_only]] int CRYPTO_num_locks(void); -[[mkcgo::c_only]] int CRYPTO_THREADID_set_callback(threadid_func fn); -[[mkcgo::c_only]] void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID_PTR id, unsigned long val); -[[mkcgo::c_only]] void CRYPTO_set_locking_callback(locking_func fn); +/*[[mkcgo::c_only]]*/ int CRYPTO_num_locks(void); +/*[[mkcgo::c_only]]*/ int CRYPTO_THREADID_set_callback(threadid_func fn); +/*[[mkcgo::c_only]]*/ void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID_PTR id, unsigned long val); +/*[[mkcgo::c_only]]*/ void CRYPTO_set_locking_callback(locking_func fn); -[[mkcgo::name("_SSLeay_version")]] const char *SSLeay_version(int typ); -[[mkcgo::name("_OpenSSL_version")]] const char *OpenSSL_version(int typ); +/*[[mkcgo::name("_SSLeay_version")]]*/ const char *SSLeay_version(int typ); +/*[[mkcgo::name("_OpenSSL_version")]]*/ const char *OpenSSL_version(int typ); void OPENSSL_init(void); void OPENSSL_add_all_algorithms_conf(void); -[[mkcgo::error_only]] int OPENSSL_init_crypto(uint64_t ops, const OPENSSL_INIT_SETTINGS_PTR settings); +/*[[mkcgo::error_only]]*/ int OPENSSL_init_crypto(uint64_t ops, const OPENSSL_INIT_SETTINGS_PTR settings); void *CRYPTO_malloc(size_t num, const char *file, int line); void CRYPTO_free(void *str, const char *file, int line); int FIPS_mode(void); -[[mkcgo::error_only]] int FIPS_mode_set(int r); +/*[[mkcgo::error_only]]*/ int FIPS_mode_set(int r); int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX_PTR libctx); -[[mkcgo::error_only]] int EVP_default_properties_enable_fips(OSSL_LIB_CTX_PTR libctx, int enable); +/*[[mkcgo::error_only]]*/ int EVP_default_properties_enable_fips(OSSL_LIB_CTX_PTR libctx, int enable); -[[mkcgo::error_only]] int RAND_bytes(unsigned char *buf, int num); +/*[[mkcgo::error_only]]*/ int RAND_bytes(unsigned char *buf, int num); EVP_CIPHER_PTR EVP_aes_128_gcm(void); EVP_CIPHER_PTR EVP_aes_192_gcm(void); @@ -53,44 +53,44 @@ EVP_CIPHER_PTR EVP_des_ede3_cbc(void); EVP_CIPHER_PTR EVP_des_ede3_ecb(void); EVP_CIPHER_PTR EVP_rc4(void); -[[mkcgo::error]] EVP_CIPHER_PTR EVP_CIPHER_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); -[[mkcgo::error]] EVP_CIPHER_CTX_PTR EVP_CIPHER_CTX_new(void); +/*[[mkcgo::error]]*/ EVP_CIPHER_PTR EVP_CIPHER_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +/*[[mkcgo::error]]*/ EVP_CIPHER_CTX_PTR EVP_CIPHER_CTX_new(void); void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX_PTR ctx); -[[mkcgo::error_only]] int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX_PTR ctx, int cmd, int p1, void *p2); -[[mkcgo::error_only]] int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX_PTR x, int padding); -[[mkcgo::name("_EVP_CIPHER_block_size")]] int EVP_CIPHER_block_size(const EVP_CIPHER_PTR e); -[[mkcgo::name("_EVP_CIPHER_get_block_size")]] int EVP_CIPHER_get_block_size(const EVP_CIPHER_PTR e); +/*[[mkcgo::error_only]]*/ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX_PTR ctx, int cmd, int p1, void *p2); +/*[[mkcgo::error_only]]*/ int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX_PTR x, int padding); +/*[[mkcgo::name("_EVP_CIPHER_block_size")]]*/ int EVP_CIPHER_block_size(const EVP_CIPHER_PTR e); +/*[[mkcgo::name("_EVP_CIPHER_get_block_size")]]*/ int EVP_CIPHER_get_block_size(const EVP_CIPHER_PTR e); const char *EVP_CIPHER_get0_name(const EVP_CIPHER_PTR cipher); -[[mkcgo::error_only]] int EVP_CipherInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv, int enc); -[[mkcgo::error_only]] int EVP_CipherUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); -[[mkcgo::error_only]] int EVP_EncryptInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv); -[[mkcgo::error_only]] int EVP_EncryptUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); -[[mkcgo::error_only]] int EVP_EncryptFinal_ex(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl); -[[mkcgo::error_only]] int EVP_DecryptInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv); -[[mkcgo::error_only]] int EVP_DecryptUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); -[[mkcgo::error_only]] int EVP_DecryptFinal_ex(EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl); -[[mkcgo::error_only]] int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX_PTR ctx, int keylen); +/*[[mkcgo::error_only]]*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv, int enc); +/*[[mkcgo::error_only]]*/ int EVP_CipherUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +/*[[mkcgo::error_only]]*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv); +/*[[mkcgo::error_only]]*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +/*[[mkcgo::error_only]]*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl); +/*[[mkcgo::error_only]]*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX_PTR ctx, const EVP_CIPHER_PTR typ, ENGINE_PTR impl, const unsigned char *key, const unsigned char *iv); +/*[[mkcgo::error_only]]*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX_PTR ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); +/*[[mkcgo::error_only]]*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX_PTR ctx, unsigned char *outm, int *outl); +/*[[mkcgo::error_only]]*/ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX_PTR ctx, int keylen); void EVP_PKEY_free(EVP_PKEY_PTR key); -[[mkcgo::name("_EVP_PKEY_size")]] int EVP_PKEY_size(const EVP_PKEY_PTR pkey); -[[mkcgo::name("_EVP_PKEY_get_size")]] int EVP_PKEY_get_size(const EVP_PKEY_PTR pkey); -[[mkcgo::name("_EVP_PKEY_bits")]] int EVP_PKEY_bits(const EVP_PKEY_PTR pkey); -[[mkcgo::name("_EVP_PKEY_get_bits")]] int EVP_PKEY_get_bits(const EVP_PKEY_PTR pkey); -[[mkcgo::error]] EVP_PKEY_PTR EVP_PKEY_new(void); -[[mkcgo::error]] EVP_PKEY_PTR EVP_PKEY_new_raw_private_key(int typ, ENGINE_PTR e, const unsigned char *key, size_t keylen); -[[mkcgo::error]] EVP_PKEY_PTR EVP_PKEY_new_raw_public_key(int typ, ENGINE_PTR e, const unsigned char *key, size_t keylen); -[[mkcgo::error("retval == 0")]] size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY_PTR pkey, unsigned char **ppub); -[[mkcgo::error]] RSA_PTR EVP_PKEY_get1_RSA(EVP_PKEY_PTR pkey); -[[mkcgo::error]] const DSA_PTR EVP_PKEY_get0_DSA(const EVP_PKEY_PTR pkey); -[[mkcgo::error]] const EC_KEY_PTR EVP_PKEY_get0_EC_KEY(const EVP_PKEY_PTR pkey); -[[mkcgo::error]] void *EVP_PKEY_get0(const EVP_PKEY_PTR pkey); -[[mkcgo::error_only]] int EVP_PKEY_up_ref(EVP_PKEY_PTR key); -[[mkcgo::error_only]] int EVP_PKEY_assign(EVP_PKEY_PTR pkey, int typ, void *key); -[[mkcgo::error_only]] int EVP_PKEY_get_raw_private_key(const EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len); -[[mkcgo::error_only]] int EVP_PKEY_get_raw_public_key(const EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len); -[[mkcgo::error_only]] int EVP_PKEY_set1_encoded_public_key(EVP_PKEY_PTR pkey, const unsigned char *pub, size_t publen); -[[mkcgo::error_only]] int EVP_PKEY_set1_EC_KEY(EVP_PKEY_PTR pkey, EC_KEY_PTR key); -[[mkcgo::error_only]] int EVP_PKEY_get_bn_param(const EVP_PKEY_PTR pkey, const char *key_name, BIGNUM_PTR *bn); +/*[[mkcgo::name("_EVP_PKEY_size")]]*/ int EVP_PKEY_size(const EVP_PKEY_PTR pkey); +/*[[mkcgo::name("_EVP_PKEY_get_size")]]*/ int EVP_PKEY_get_size(const EVP_PKEY_PTR pkey); +/*[[mkcgo::name("_EVP_PKEY_bits")]]*/ int EVP_PKEY_bits(const EVP_PKEY_PTR pkey); +/*[[mkcgo::name("_EVP_PKEY_get_bits")]]*/ int EVP_PKEY_get_bits(const EVP_PKEY_PTR pkey); +/*[[mkcgo::error]]*/ EVP_PKEY_PTR EVP_PKEY_new(void); +/*[[mkcgo::error]]*/ EVP_PKEY_PTR EVP_PKEY_new_raw_private_key(int typ, ENGINE_PTR e, const unsigned char *key, size_t keylen); +/*[[mkcgo::error]]*/ EVP_PKEY_PTR EVP_PKEY_new_raw_public_key(int typ, ENGINE_PTR e, const unsigned char *key, size_t keylen); +/*[[mkcgo::error("retval == 0")]]*/ size_t EVP_PKEY_get1_encoded_public_key(EVP_PKEY_PTR pkey, unsigned char **ppub); +/*[[mkcgo::error]]*/ RSA_PTR EVP_PKEY_get1_RSA(EVP_PKEY_PTR pkey); +/*[[mkcgo::error]]*/ const DSA_PTR EVP_PKEY_get0_DSA(const EVP_PKEY_PTR pkey); +/*[[mkcgo::error]]*/ const EC_KEY_PTR EVP_PKEY_get0_EC_KEY(const EVP_PKEY_PTR pkey); +/*[[mkcgo::error]]*/ void *EVP_PKEY_get0(const EVP_PKEY_PTR pkey); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_up_ref(EVP_PKEY_PTR key); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_assign(EVP_PKEY_PTR pkey, int typ, void *key); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_get_raw_private_key(const EVP_PKEY_PTR pkey, unsigned char *priv, size_t *len); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_get_raw_public_key(const EVP_PKEY_PTR pkey, unsigned char *pub, size_t *len); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_set1_encoded_public_key(EVP_PKEY_PTR pkey, const unsigned char *pub, size_t publen); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_set1_EC_KEY(EVP_PKEY_PTR pkey, EC_KEY_PTR key); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_get_bn_param(const EVP_PKEY_PTR pkey, const char *key_name, BIGNUM_PTR *bn); const EVP_MD_PTR EVP_md5_sha1(void); const EVP_MD_PTR EVP_md4(void); @@ -106,164 +106,164 @@ const EVP_MD_PTR EVP_sha3_384(void); const EVP_MD_PTR EVP_sha3_512(void); void EC_KEY_free(EC_KEY_PTR arg0); -[[mkcgo::error]] const EC_GROUP_PTR EC_KEY_get0_group(const EC_KEY_PTR arg0); -[[mkcgo::error]] const BIGNUM_PTR EC_KEY_get0_private_key(const EC_KEY_PTR arg0); -[[mkcgo::error]] const EC_POINT_PTR EC_KEY_get0_public_key(const EC_KEY_PTR arg0); -[[mkcgo::error]] EC_KEY_PTR EC_KEY_new_by_curve_name(int arg0); -[[mkcgo::error_only]] int EC_KEY_set_public_key_affine_coordinates(EC_KEY_PTR key, BIGNUM_PTR x, BIGNUM_PTR y); -[[mkcgo::error_only]] int EC_KEY_set_public_key(EC_KEY_PTR key, const EC_POINT_PTR pub); -[[mkcgo::error_only]] int EC_KEY_set_private_key(EC_KEY_PTR arg0, const BIGNUM_PTR arg1); +/*[[mkcgo::error]]*/ const EC_GROUP_PTR EC_KEY_get0_group(const EC_KEY_PTR arg0); +/*[[mkcgo::error]]*/ const BIGNUM_PTR EC_KEY_get0_private_key(const EC_KEY_PTR arg0); +/*[[mkcgo::error]]*/ const EC_POINT_PTR EC_KEY_get0_public_key(const EC_KEY_PTR arg0); +/*[[mkcgo::error]]*/ EC_KEY_PTR EC_KEY_new_by_curve_name(int arg0); +/*[[mkcgo::error_only]]*/ int EC_KEY_set_public_key_affine_coordinates(EC_KEY_PTR key, BIGNUM_PTR x, BIGNUM_PTR y); +/*[[mkcgo::error_only]]*/ int EC_KEY_set_public_key(EC_KEY_PTR key, const EC_POINT_PTR pub); +/*[[mkcgo::error_only]]*/ int EC_KEY_set_private_key(EC_KEY_PTR arg0, const BIGNUM_PTR arg1); void EVP_PKEY_CTX_free(EVP_PKEY_CTX_PTR arg0); -[[mkcgo::error]] EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new(EVP_PKEY_PTR arg0, ENGINE_PTR arg1); -[[mkcgo::error]] EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_id(int id, ENGINE_PTR e); -[[mkcgo::error]] EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX_PTR libctx, EVP_PKEY_PTR pkey, const char *propquery); -[[mkcgo::error_only]] int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2); -[[mkcgo::error_only]] int EVP_PKEY_decrypt(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); -[[mkcgo::error_only]] int EVP_PKEY_encrypt(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); -[[mkcgo::error_only]] int EVP_PKEY_decrypt_init(EVP_PKEY_CTX_PTR arg0); -[[mkcgo::error_only]] int EVP_PKEY_encrypt_init(EVP_PKEY_CTX_PTR arg0); -[[mkcgo::error_only]] int EVP_PKEY_sign_init(EVP_PKEY_CTX_PTR arg0); -[[mkcgo::error_only]] int EVP_PKEY_verify_init(EVP_PKEY_CTX_PTR arg0); -[[mkcgo::error_only]] int EVP_PKEY_verify(EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); -[[mkcgo::error_only]] int EVP_PKEY_sign(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); -[[mkcgo::error_only]] int EVP_PKEY_derive_init(EVP_PKEY_CTX_PTR ctx); -[[mkcgo::error_only]] int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR peer); -[[mkcgo::error_only]] int EVP_PKEY_derive(EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t *keylen); -[[mkcgo::error_only]] int EVP_PKEY_fromdata_init(EVP_PKEY_CTX_PTR ctx); -[[mkcgo::error_only]] int EVP_PKEY_fromdata(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *pkey, int selection, OSSL_PARAM_PTR params); -[[mkcgo::error_only]] int EVP_PKEY_paramgen_init(EVP_PKEY_CTX_PTR ctx); -[[mkcgo::error_only]] int EVP_PKEY_paramgen(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *ppkey); -[[mkcgo::error_only]] int EVP_PKEY_keygen_init(EVP_PKEY_CTX_PTR ctx); -[[mkcgo::error_only]] int EVP_PKEY_keygen(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *ppkey); -[[mkcgo::error_only]] int EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX_PTR arg0, int arg1); -[[mkcgo::error_only]] int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX_PTR arg0, const EVP_MD_PTR arg1); -[[mkcgo::error_only]] int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); -[[mkcgo::error_only]] int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); -[[mkcgo::error_only]] int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); -[[mkcgo::error_only]] int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX_PTR ctx, void *label, int len); -[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]] EVP_PKEY_PTR EVP_PKEY_Q_keygen_ED25519(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ); -[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]] EVP_PKEY_PTR EVP_PKEY_Q_keygen_RSA(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ, size_t arg1); -[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]] EVP_PKEY_PTR EVP_PKEY_Q_keygen_EC(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ, const char *arg1); +/*[[mkcgo::error]]*/ EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new(EVP_PKEY_PTR arg0, ENGINE_PTR arg1); +/*[[mkcgo::error]]*/ EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_id(int id, ENGINE_PTR e); +/*[[mkcgo::error]]*/ EVP_PKEY_CTX_PTR EVP_PKEY_CTX_new_from_pkey(OSSL_LIB_CTX_PTR libctx, EVP_PKEY_PTR pkey, const char *propquery); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX_PTR ctx, int keytype, int optype, int cmd, int p1, void *p2); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_decrypt(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_encrypt(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX_PTR arg0); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX_PTR arg0); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_sign_init(EVP_PKEY_CTX_PTR arg0); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_verify_init(EVP_PKEY_CTX_PTR arg0); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_verify(EVP_PKEY_CTX_PTR ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_sign(EVP_PKEY_CTX_PTR arg0, unsigned char *arg1, size_t *arg2, const unsigned char *arg3, size_t arg4); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_derive_init(EVP_PKEY_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR peer); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_derive(EVP_PKEY_CTX_PTR ctx, unsigned char *key, size_t *keylen); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_fromdata_init(EVP_PKEY_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_fromdata(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *pkey, int selection, OSSL_PARAM_PTR params); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_paramgen_init(EVP_PKEY_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_paramgen(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *ppkey); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_keygen_init(EVP_PKEY_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_keygen(EVP_PKEY_CTX_PTR ctx, EVP_PKEY_PTR *ppkey); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_set_hkdf_mode(EVP_PKEY_CTX_PTR arg0, int arg1); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_set_hkdf_md(EVP_PKEY_CTX_PTR arg0, const EVP_MD_PTR arg1); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_set1_hkdf_salt(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX_PTR arg0, const unsigned char *arg1, int arg2); +/*[[mkcgo::error_only]]*/ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX_PTR ctx, void *label, int len); +/*[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]]*/ EVP_PKEY_PTR EVP_PKEY_Q_keygen_ED25519(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ); +/*[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]]*/ EVP_PKEY_PTR EVP_PKEY_Q_keygen_RSA(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ, size_t arg1); +/*[[mkcgo::error]] [[mkcgo::variadic("EVP_PKEY_Q_keygen")]]*/ EVP_PKEY_PTR EVP_PKEY_Q_keygen_EC(OSSL_LIB_CTX_PTR ctx, const char *propq, const char *typ, const char *arg1); void RSA_free(RSA_PTR r); void RSA_get0_crt_params(const RSA_PTR r, const BIGNUM_PTR *dmp1, const BIGNUM_PTR *dmq1, const BIGNUM_PTR *iqmp); void RSA_get0_factors(const RSA_PTR r, const BIGNUM_PTR *p, const BIGNUM_PTR *q); void RSA_get0_key(const RSA_PTR r, const BIGNUM_PTR *n, const BIGNUM_PTR *e, const BIGNUM_PTR *d); -[[mkcgo::error]] RSA_PTR RSA_new(void); -[[mkcgo::error_only]] int RSA_set0_key(RSA_PTR r, BIGNUM_PTR n, BIGNUM_PTR e, BIGNUM_PTR d); -[[mkcgo::error_only]] int RSA_set0_factors(RSA_PTR r, BIGNUM_PTR p, BIGNUM_PTR q); -[[mkcgo::error_only]] int RSA_set0_crt_params(RSA_PTR r, BIGNUM_PTR dmp1, BIGNUM_PTR dmq1, BIGNUM_PTR iqmp); +/*[[mkcgo::error]]*/ RSA_PTR RSA_new(void); +/*[[mkcgo::error_only]]*/ int RSA_set0_key(RSA_PTR r, BIGNUM_PTR n, BIGNUM_PTR e, BIGNUM_PTR d); +/*[[mkcgo::error_only]]*/ int RSA_set0_factors(RSA_PTR r, BIGNUM_PTR p, BIGNUM_PTR q); +/*[[mkcgo::error_only]]*/ int RSA_set0_crt_params(RSA_PTR r, BIGNUM_PTR dmp1, BIGNUM_PTR dmq1, BIGNUM_PTR iqmp); void DSA_free(DSA_PTR r); void DSA_get0_pqg(const DSA_PTR d, const BIGNUM_PTR *p, const BIGNUM_PTR *q, const BIGNUM_PTR *g); void DSA_get0_key(const DSA_PTR d, const BIGNUM_PTR *pub_key, const BIGNUM_PTR *priv_key); -[[mkcgo::error]] DSA_PTR DSA_new(void); -[[mkcgo::error_only]] int DSA_generate_key(DSA_PTR a); -[[mkcgo::error_only]] int DSA_set0_pqg(DSA_PTR d, BIGNUM_PTR p, BIGNUM_PTR q, BIGNUM_PTR g); -[[mkcgo::error_only]] int DSA_set0_key(DSA_PTR d, BIGNUM_PTR pub_key, BIGNUM_PTR priv_key); +/*[[mkcgo::error]]*/ DSA_PTR DSA_new(void); +/*[[mkcgo::error_only]]*/ int DSA_generate_key(DSA_PTR a); +/*[[mkcgo::error_only]]*/ int DSA_set0_pqg(DSA_PTR d, BIGNUM_PTR p, BIGNUM_PTR q, BIGNUM_PTR g); +/*[[mkcgo::error_only]]*/ int DSA_set0_key(DSA_PTR d, BIGNUM_PTR pub_key, BIGNUM_PTR priv_key); void HMAC_CTX_free(HMAC_CTX_PTR arg0); void HMAC_CTX_init(HMAC_CTX_PTR arg0); void HMAC_CTX_cleanup(HMAC_CTX_PTR arg0); -[[mkcgo::error]] HMAC_CTX_PTR HMAC_CTX_new(void); -[[mkcgo::error_only]] int HMAC_CTX_copy(HMAC_CTX_PTR dest, HMAC_CTX_PTR src); -[[mkcgo::error_only]] int HMAC_Init_ex(HMAC_CTX_PTR arg0, const void *arg1, int arg2, const EVP_MD_PTR arg3, ENGINE_PTR arg4); -[[mkcgo::error_only]] int HMAC_Update(HMAC_CTX_PTR arg0, const unsigned char *arg1, size_t arg2); -[[mkcgo::error_only]] int HMAC_Final(HMAC_CTX_PTR arg0, unsigned char *arg1, unsigned int *arg2); +/*[[mkcgo::error]]*/ HMAC_CTX_PTR HMAC_CTX_new(void); +/*[[mkcgo::error_only]]*/ int HMAC_CTX_copy(HMAC_CTX_PTR dest, HMAC_CTX_PTR src); +/*[[mkcgo::error_only]]*/ int HMAC_Init_ex(HMAC_CTX_PTR arg0, const void *arg1, int arg2, const EVP_MD_PTR arg3, ENGINE_PTR arg4); +/*[[mkcgo::error_only]]*/ int HMAC_Update(HMAC_CTX_PTR arg0, const unsigned char *arg1, size_t arg2); +/*[[mkcgo::error_only]]*/ int HMAC_Final(HMAC_CTX_PTR arg0, unsigned char *arg1, unsigned int *arg2); int OSSL_PROVIDER_available(OSSL_LIB_CTX_PTR libctx, const char *name); -[[mkcgo::error]] OSSL_PROVIDER_PTR OSSL_PROVIDER_try_load(OSSL_LIB_CTX_PTR libctx, const char *name, int retain_fallbacks); +/*[[mkcgo::error]]*/ OSSL_PROVIDER_PTR OSSL_PROVIDER_try_load(OSSL_LIB_CTX_PTR libctx, const char *name, int retain_fallbacks); const char *OSSL_PROVIDER_get0_name(const OSSL_PROVIDER_PTR prov); void EVP_MD_free(EVP_MD_PTR md); const char *EVP_MD_get0_name(const EVP_MD_PTR md); -[[mkcgo::name("_EVP_MD_size")]] int EVP_MD_size(const EVP_MD_PTR md); -[[mkcgo::name("_EVP_MD_get_size")]] int EVP_MD_get_size(const EVP_MD_PTR md); -[[mkcgo::name("_EVP_MD_block_size")]] int EVP_MD_block_size(const EVP_MD_PTR md); -[[mkcgo::name("_EVP_MD_get_block_size")]] int EVP_MD_get_block_size(const EVP_MD_PTR md); -[[mkcgo::name("_EVP_MD_CTX_destroy")]] void EVP_MD_CTX_destroy(EVP_MD_CTX_PTR ctx); -[[mkcgo::name("_EVP_MD_CTX_free")]] void EVP_MD_CTX_free(EVP_MD_CTX_PTR ctx); -[[mkcgo::error]] [[mkcgo::name("_EVP_MD_CTX_create")]] EVP_MD_CTX_PTR EVP_MD_CTX_create(void); -[[mkcgo::error]] [[mkcgo::name("_EVP_MD_CTX_new")]] EVP_MD_CTX_PTR EVP_MD_CTX_new(void); -[[mkcgo::error]] const OSSL_PROVIDER_PTR EVP_MD_get0_provider(const EVP_MD_PTR md); -[[mkcgo::error]] EVP_MD_PTR EVP_MD_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); -[[mkcgo::error_only]] int EVP_MD_CTX_copy(EVP_MD_CTX_PTR out, const EVP_MD_CTX_PTR in); -[[mkcgo::error_only]] int EVP_MD_CTX_copy_ex(EVP_MD_CTX_PTR out, const EVP_MD_CTX_PTR in); -[[mkcgo::error_only]] int EVP_Digest(const void *data, size_t count, unsigned char *md, unsigned int *size, const EVP_MD_PTR typ, ENGINE_PTR impl); -[[mkcgo::error_only]] int EVP_DigestInit_ex(EVP_MD_CTX_PTR ctx, const EVP_MD_PTR typ, ENGINE_PTR impl); -[[mkcgo::error_only]] int EVP_DigestInit(EVP_MD_CTX_PTR ctx, const EVP_MD_PTR typ); -[[mkcgo::error_only]] int EVP_DigestUpdate(EVP_MD_CTX_PTR ctx, const void *d, size_t cnt); -[[mkcgo::error_only]] int EVP_DigestFinal(EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s); -[[mkcgo::error_only]] int EVP_DigestSign(EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen); -[[mkcgo::error_only]] int EVP_DigestSignInit(EVP_MD_CTX_PTR ctx, EVP_PKEY_CTX_PTR *pctx, const EVP_MD_PTR typ, ENGINE_PTR e, EVP_PKEY_PTR pkey); -[[mkcgo::error_only]] int EVP_DigestSignFinal(EVP_MD_CTX_PTR ctx, unsigned char *sig, size_t *siglen); -[[mkcgo::error_only]] int EVP_DigestVerifyInit(EVP_MD_CTX_PTR ctx, EVP_PKEY_CTX_PTR *pctx, const EVP_MD_PTR typ, ENGINE_PTR e, EVP_PKEY_PTR pkey); -[[mkcgo::error_only]] int EVP_DigestVerifyFinal(EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen); -[[mkcgo::error_only]] int EVP_DigestVerify(EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen); -[[mkcgo::error_only]] int MD5_Init(MD5_CTX_PTR c); -[[mkcgo::error_only]] int MD5_Update(MD5_CTX_PTR c, const void *data, size_t len); -[[mkcgo::error_only]] int MD5_Final(unsigned char *md, MD5_CTX_PTR c); -[[mkcgo::error_only]] int SHA1_Init(SHA_CTX_PTR c); -[[mkcgo::error_only]] int SHA1_Update(SHA_CTX_PTR c, const void *data, size_t len); -[[mkcgo::error_only]] int SHA1_Final(unsigned char *md, SHA_CTX_PTR c); +/*[[mkcgo::name("_EVP_MD_size")]]*/ int EVP_MD_size(const EVP_MD_PTR md); +/*[[mkcgo::name("_EVP_MD_get_size")]]*/ int EVP_MD_get_size(const EVP_MD_PTR md); +/*[[mkcgo::name("_EVP_MD_block_size")]]*/ int EVP_MD_block_size(const EVP_MD_PTR md); +/*[[mkcgo::name("_EVP_MD_get_block_size")]]*/ int EVP_MD_get_block_size(const EVP_MD_PTR md); +/*[[mkcgo::name("_EVP_MD_CTX_destroy")]]*/ void EVP_MD_CTX_destroy(EVP_MD_CTX_PTR ctx); +/*[[mkcgo::name("_EVP_MD_CTX_free")]]*/ void EVP_MD_CTX_free(EVP_MD_CTX_PTR ctx); +/*[[mkcgo::error]] [[mkcgo::name("_EVP_MD_CTX_create")]]*/ EVP_MD_CTX_PTR EVP_MD_CTX_create(void); +/*[[mkcgo::error]] [[mkcgo::name("_EVP_MD_CTX_new")]]*/ EVP_MD_CTX_PTR EVP_MD_CTX_new(void); +/*[[mkcgo::error]]*/ const OSSL_PROVIDER_PTR EVP_MD_get0_provider(const EVP_MD_PTR md); +/*[[mkcgo::error]]*/ EVP_MD_PTR EVP_MD_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +/*[[mkcgo::error_only]]*/ int EVP_MD_CTX_copy(EVP_MD_CTX_PTR out, const EVP_MD_CTX_PTR in); +/*[[mkcgo::error_only]]*/ int EVP_MD_CTX_copy_ex(EVP_MD_CTX_PTR out, const EVP_MD_CTX_PTR in); +/*[[mkcgo::error_only]]*/ int EVP_Digest(const void *data, size_t count, unsigned char *md, unsigned int *size, const EVP_MD_PTR typ, ENGINE_PTR impl); +/*[[mkcgo::error_only]]*/ int EVP_DigestInit_ex(EVP_MD_CTX_PTR ctx, const EVP_MD_PTR typ, ENGINE_PTR impl); +/*[[mkcgo::error_only]]*/ int EVP_DigestInit(EVP_MD_CTX_PTR ctx, const EVP_MD_PTR typ); +/*[[mkcgo::error_only]]*/ int EVP_DigestUpdate(EVP_MD_CTX_PTR ctx, const void *d, size_t cnt); +/*[[mkcgo::error_only]]*/ int EVP_DigestFinal(EVP_MD_CTX_PTR ctx, unsigned char *md, unsigned int *s); +/*[[mkcgo::error_only]]*/ int EVP_DigestSign(EVP_MD_CTX_PTR ctx, unsigned char *sigret, size_t *siglen, const unsigned char *tbs, size_t tbslen); +/*[[mkcgo::error_only]]*/ int EVP_DigestSignInit(EVP_MD_CTX_PTR ctx, EVP_PKEY_CTX_PTR *pctx, const EVP_MD_PTR typ, ENGINE_PTR e, EVP_PKEY_PTR pkey); +/*[[mkcgo::error_only]]*/ int EVP_DigestSignFinal(EVP_MD_CTX_PTR ctx, unsigned char *sig, size_t *siglen); +/*[[mkcgo::error_only]]*/ int EVP_DigestVerifyInit(EVP_MD_CTX_PTR ctx, EVP_PKEY_CTX_PTR *pctx, const EVP_MD_PTR typ, ENGINE_PTR e, EVP_PKEY_PTR pkey); +/*[[mkcgo::error_only]]*/ int EVP_DigestVerifyFinal(EVP_MD_CTX_PTR ctx, const unsigned char *sig, size_t siglen); +/*[[mkcgo::error_only]]*/ int EVP_DigestVerify(EVP_MD_CTX_PTR ctx, const unsigned char *sigret, size_t siglen, const unsigned char *tbs, size_t tbslen); +/*[[mkcgo::error_only]]*/ int MD5_Init(MD5_CTX_PTR c); +/*[[mkcgo::error_only]]*/ int MD5_Update(MD5_CTX_PTR c, const void *data, size_t len); +/*[[mkcgo::error_only]]*/ int MD5_Final(unsigned char *md, MD5_CTX_PTR c); +/*[[mkcgo::error_only]]*/ int SHA1_Init(SHA_CTX_PTR c); +/*[[mkcgo::error_only]]*/ int SHA1_Update(SHA_CTX_PTR c, const void *data, size_t len); +/*[[mkcgo::error_only]]*/ int SHA1_Final(unsigned char *md, SHA_CTX_PTR c); void BN_free(BIGNUM_PTR arg0); void BN_clear(BIGNUM_PTR arg0); void BN_clear_free(BIGNUM_PTR arg0); int BN_num_bits(const BIGNUM_PTR arg0); int BN_bn2bin(const BIGNUM_PTR a, unsigned char *to); -[[mkcgo::error]] BIGNUM_PTR BN_new(void); -[[mkcgo::error]] BIGNUM_PTR BN_bin2bn(const unsigned char *arg0, int arg1, BIGNUM_PTR arg2); -[[mkcgo::error]] [[mkcgo::name("BN_expand2")]] BIGNUM_PTR bn_expand2(BIGNUM_PTR a, int n); -[[mkcgo::error]] BIGNUM_PTR BN_lebin2bn(const unsigned char *s, int len, BIGNUM_PTR ret); -[[mkcgo::error("retval == -1")]] int BN_bn2lebinpad(const BIGNUM_PTR a, unsigned char *to, int tolen); -[[mkcgo::error("retval == -1")]] int BN_bn2binpad(const BIGNUM_PTR a, unsigned char *to, int tolen); +/*[[mkcgo::error]]*/ BIGNUM_PTR BN_new(void); +/*[[mkcgo::error]]*/ BIGNUM_PTR BN_bin2bn(const unsigned char *arg0, int arg1, BIGNUM_PTR arg2); +/*[[mkcgo::error]] [[mkcgo::name("BN_expand2")]]*/ BIGNUM_PTR bn_expand2(BIGNUM_PTR a, int n); +/*[[mkcgo::error]]*/ BIGNUM_PTR BN_lebin2bn(const unsigned char *s, int len, BIGNUM_PTR ret); +/*[[mkcgo::error("retval == -1")]]*/ int BN_bn2lebinpad(const BIGNUM_PTR a, unsigned char *to, int tolen); +/*[[mkcgo::error("retval == -1")]]*/ int BN_bn2binpad(const BIGNUM_PTR a, unsigned char *to, int tolen); void EC_POINT_free(EC_POINT_PTR arg0); -[[mkcgo::error]] EC_POINT_PTR EC_POINT_new(const EC_GROUP_PTR arg0); -[[mkcgo::error("retval == 0")]] size_t EC_POINT_point2oct(const EC_GROUP_PTR group, const EC_POINT_PTR p, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX_PTR ctx); -[[mkcgo::error_only]] int EC_POINT_mul(const EC_GROUP_PTR group, EC_POINT_PTR r, const BIGNUM_PTR n, const EC_POINT_PTR q, const BIGNUM_PTR m, BN_CTX_PTR ctx); -[[mkcgo::error_only]] int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP_PTR arg0, const EC_POINT_PTR arg1, BIGNUM_PTR arg2, BIGNUM_PTR arg3, BN_CTX_PTR arg4); -[[mkcgo::error_only]] int EC_POINT_set_affine_coordinates(const EC_GROUP_PTR arg0, EC_POINT_PTR arg1, const BIGNUM_PTR arg2, const BIGNUM_PTR arg3, BN_CTX_PTR arg4); -[[mkcgo::error_only]] int EC_POINT_oct2point(const EC_GROUP_PTR group, EC_POINT_PTR p, const unsigned char *buf, size_t len, BN_CTX_PTR ctx); +/*[[mkcgo::error]]*/ EC_POINT_PTR EC_POINT_new(const EC_GROUP_PTR arg0); +/*[[mkcgo::error("retval == 0")]]*/ size_t EC_POINT_point2oct(const EC_GROUP_PTR group, const EC_POINT_PTR p, point_conversion_form_t form, unsigned char *buf, size_t len, BN_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EC_POINT_mul(const EC_GROUP_PTR group, EC_POINT_PTR r, const BIGNUM_PTR n, const EC_POINT_PTR q, const BIGNUM_PTR m, BN_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP_PTR arg0, const EC_POINT_PTR arg1, BIGNUM_PTR arg2, BIGNUM_PTR arg3, BN_CTX_PTR arg4); +/*[[mkcgo::error_only]]*/ int EC_POINT_set_affine_coordinates(const EC_GROUP_PTR arg0, EC_POINT_PTR arg1, const BIGNUM_PTR arg2, const BIGNUM_PTR arg3, BN_CTX_PTR arg4); +/*[[mkcgo::error_only]]*/ int EC_POINT_oct2point(const EC_GROUP_PTR group, EC_POINT_PTR p, const unsigned char *buf, size_t len, BN_CTX_PTR ctx); const char *OBJ_nid2sn(int n); -[[mkcgo::error]] EC_GROUP_PTR EC_GROUP_new_by_curve_name(int nid); +/*[[mkcgo::error]]*/ EC_GROUP_PTR EC_GROUP_new_by_curve_name(int nid); void EC_GROUP_free(EC_GROUP_PTR group); void EVP_MAC_CTX_free(EVP_MAC_CTX_PTR arg0); -[[mkcgo::error]] EVP_MAC_PTR EVP_MAC_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); -[[mkcgo::error]] EVP_MAC_CTX_PTR EVP_MAC_CTX_new(EVP_MAC_PTR arg0); -[[mkcgo::error]] EVP_MAC_CTX_PTR EVP_MAC_CTX_dup(const EVP_MAC_CTX_PTR arg0); -[[mkcgo::error_only]] int EVP_MAC_CTX_set_params(EVP_MAC_CTX_PTR ctx, const OSSL_PARAM_PTR params); -[[mkcgo::error_only]] int EVP_MAC_init(EVP_MAC_CTX_PTR ctx, const unsigned char *key, size_t keylen, const OSSL_PARAM_PTR params); -[[mkcgo::error_only]] int EVP_MAC_update(EVP_MAC_CTX_PTR ctx, const unsigned char *data, size_t datalen); -[[mkcgo::error_only]] int EVP_MAC_final(EVP_MAC_CTX_PTR ctx, unsigned char *out, size_t *outl, size_t outsize); +/*[[mkcgo::error]]*/ EVP_MAC_PTR EVP_MAC_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +/*[[mkcgo::error]]*/ EVP_MAC_CTX_PTR EVP_MAC_CTX_new(EVP_MAC_PTR arg0); +/*[[mkcgo::error]]*/ EVP_MAC_CTX_PTR EVP_MAC_CTX_dup(const EVP_MAC_CTX_PTR arg0); +/*[[mkcgo::error_only]]*/ int EVP_MAC_CTX_set_params(EVP_MAC_CTX_PTR ctx, const OSSL_PARAM_PTR params); +/*[[mkcgo::error_only]]*/ int EVP_MAC_init(EVP_MAC_CTX_PTR ctx, const unsigned char *key, size_t keylen, const OSSL_PARAM_PTR params); +/*[[mkcgo::error_only]]*/ int EVP_MAC_update(EVP_MAC_CTX_PTR ctx, const unsigned char *data, size_t datalen); +/*[[mkcgo::error_only]]*/ int EVP_MAC_final(EVP_MAC_CTX_PTR ctx, unsigned char *out, size_t *outl, size_t outsize); void OSSL_PARAM_free(OSSL_PARAM_PTR p); void OSSL_PARAM_BLD_free(OSSL_PARAM_BLD_PTR bld); -[[mkcgo::error]] OSSL_PARAM_BLD_PTR OSSL_PARAM_BLD_new(void); -[[mkcgo::error]] OSSL_PARAM_PTR OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD_PTR bld); -[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD_PTR bld, const char *key, const char *buf, size_t bsize); -[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD_PTR bld, const char *key, const void *buf, size_t bsize); -[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD_PTR bld, const char *key, const BIGNUM_PTR bn); -[[mkcgo::error_only]] int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD_PTR bld, const char *key, int32_t num); +/*[[mkcgo::error]]*/ OSSL_PARAM_BLD_PTR OSSL_PARAM_BLD_new(void); +/*[[mkcgo::error]]*/ OSSL_PARAM_PTR OSSL_PARAM_BLD_to_param(OSSL_PARAM_BLD_PTR bld); +/*[[mkcgo::error_only]]*/ int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD_PTR bld, const char *key, const char *buf, size_t bsize); +/*[[mkcgo::error_only]]*/ int OSSL_PARAM_BLD_push_octet_string(OSSL_PARAM_BLD_PTR bld, const char *key, const void *buf, size_t bsize); +/*[[mkcgo::error_only]]*/ int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD_PTR bld, const char *key, const BIGNUM_PTR bn); +/*[[mkcgo::error_only]]*/ int OSSL_PARAM_BLD_push_int32(OSSL_PARAM_BLD_PTR bld, const char *key, int32_t num); -[[mkcgo::error_only]] int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD_PTR digest, int keylen, unsigned char *out); +/*[[mkcgo::error_only]]*/ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, const EVP_MD_PTR digest, int keylen, unsigned char *out); void EVP_SIGNATURE_free(EVP_SIGNATURE_PTR signature); -[[mkcgo::error]] EVP_SIGNATURE_PTR EVP_SIGNATURE_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); +/*[[mkcgo::error]]*/ EVP_SIGNATURE_PTR EVP_SIGNATURE_fetch(OSSL_LIB_CTX_PTR ctx, const char *algorithm, const char *properties); void EVP_KDF_free(EVP_KDF_PTR kdf); -[[mkcgo::error]] EVP_KDF_CTX_PTR EVP_KDF_CTX_new(EVP_KDF_PTR kdf); -[[mkcgo::error]] EVP_KDF_PTR EVP_KDF_fetch(OSSL_LIB_CTX_PTR libctx, const char *algorithm, const char *properties); +/*[[mkcgo::error]]*/ EVP_KDF_CTX_PTR EVP_KDF_CTX_new(EVP_KDF_PTR kdf); +/*[[mkcgo::error]]*/ EVP_KDF_PTR EVP_KDF_fetch(OSSL_LIB_CTX_PTR libctx, const char *algorithm, const char *properties); void EVP_KDF_CTX_free(EVP_KDF_CTX_PTR ctx); -[[mkcgo::error("retval == 0")]] size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX_PTR ctx); -[[mkcgo::error_only]] int EVP_KDF_CTX_set_params(EVP_KDF_CTX_PTR ctx, const OSSL_PARAM_PTR params); -[[mkcgo::error_only]] int EVP_KDF_derive(EVP_KDF_CTX_PTR ctx, unsigned char *key, size_t keylen, const OSSL_PARAM_PTR params); +/*[[mkcgo::error("retval == 0")]]*/ size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX_PTR ctx); +/*[[mkcgo::error_only]]*/ int EVP_KDF_CTX_set_params(EVP_KDF_CTX_PTR ctx, const OSSL_PARAM_PTR params); +/*[[mkcgo::error_only]]*/ int EVP_KDF_derive(EVP_KDF_CTX_PTR ctx, unsigned char *key, size_t keylen, const OSSL_PARAM_PTR params); From b533ebf5fe9c5ff431f9f14dc8bce6cd9369b237 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 14:59:48 +0100 Subject: [PATCH 12/20] fix include --- internal/ossl/thread_setup_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ossl/thread_setup_unix.c b/internal/ossl/thread_setup_unix.c index b2e5adaf..44476715 100644 --- a/internal/ossl/thread_setup_unix.c +++ b/internal/ossl/thread_setup_unix.c @@ -1,6 +1,6 @@ //go:build unix -#include "ossl.h" +#include "api.h" #include "thread_setup.h" #include From ba5319bb7ed0ca0514471de635a728d01123ebc5 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 15:02:37 +0100 Subject: [PATCH 13/20] skip TestThreadCleanup --- internal/ossl/thread_setup_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/ossl/thread_setup_test.go b/internal/ossl/thread_setup_test.go index 10a70991..5426520c 100644 --- a/internal/ossl/thread_setup_test.go +++ b/internal/ossl/thread_setup_test.go @@ -18,6 +18,7 @@ func TestThreadCleanup(t *testing.T) { if vMajor > 1 || vMinor > 0 { t.Skip("explicit thread cleanup is only needed for OpenSSL 1.0.x") } + t.Skip("not supported for now") before := opensslThreadsCleanedUp() done := make(chan struct{}) From 7d74c2146db65a20e93e98d51b2d3e9af2ae0709 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 15:07:46 +0100 Subject: [PATCH 14/20] include stdlib.h --- internal/ossl/thread_setup_unix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/ossl/thread_setup_unix.c b/internal/ossl/thread_setup_unix.c index 44476715..deac8ff2 100644 --- a/internal/ossl/thread_setup_unix.c +++ b/internal/ossl/thread_setup_unix.c @@ -3,6 +3,7 @@ #include "api.h" #include "thread_setup.h" #include +#include /* This array will store all of the mutexes available to OpenSSL. */ static pthread_mutex_t *mutex_buf = NULL; From cd200c010c2ecc25f82e132ec0e764b5c8a7d640 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 15:08:18 +0100 Subject: [PATCH 15/20] remove stale prefix --- internal/ossl/thread_setup_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/ossl/thread_setup_unix.c b/internal/ossl/thread_setup_unix.c index deac8ff2..8cda87e0 100644 --- a/internal/ossl/thread_setup_unix.c +++ b/internal/ossl/thread_setup_unix.c @@ -21,7 +21,7 @@ static void locking_function(int mode, int n, const char *file, int line) pthread_mutex_unlock(&mutex_buf[n]); } -static void thread_id(GO_CRYPTO_THREADID_PTR tid) +static void thread_id(CRYPTO_THREADID_PTR tid) { CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); From 6de9c5200fb47e0374a91ab2128ee1e1f6733703 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 16:03:30 +0100 Subject: [PATCH 16/20] fix throw --- openssl.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openssl.go b/openssl.go index feb589d7..2ed7a6b9 100644 --- a/openssl.go +++ b/openssl.go @@ -313,8 +313,8 @@ func caller(skip int) (file *byte, line int32) { return (*byte)(noescape(unsafe.Pointer(unsafe.StringData(f)))), int32(l) } -//go:linkname runtime_throw runtime.throw -func runtime_throw(string) +//go:linkname throw runtime.throw +func throw(string) // cryptoMalloc allocates n bytes of memory on the OpenSSL heap, which may be // different from the heap which C.malloc allocates on. The allocated object @@ -338,7 +338,7 @@ func cryptoMalloc(n int) unsafe.Pointer { if p == nil { // Un-recover()-ably crash the program in the same manner as the // C.malloc() wrapper function. - runtime_throw("openssl: CRYPTO_malloc failed") + throw("openssl: CRYPTO_malloc failed") } return p } From e9c1e5cfb6c4639476fb4650cb6a14845964500a Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 17:40:02 +0100 Subject: [PATCH 17/20] fix error condition --- evp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evp.go b/evp.go index 5aace7ee..16d61bc5 100644 --- a/evp.go +++ b/evp.go @@ -460,7 +460,7 @@ func newEVPPKEY(key ossl.EC_KEY_PTR) (ossl.EVP_PKEY_PTR, error) { // The returned key should not be freed. func getECKey(pkey ossl.EVP_PKEY_PTR) (key ossl.EC_KEY_PTR) { if vMajor == 1 && vMinor == 0 { - if key0, err := ossl.EVP_PKEY_get0(pkey); err != nil { + if key0, err := ossl.EVP_PKEY_get0(pkey); err == nil { key = ossl.EC_KEY_PTR(key0) } } else { From 6202ba44f41eca77971612dcd2c0c8634c2e6545 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 17:46:31 +0100 Subject: [PATCH 18/20] fix ldflags --- init_unix.go | 2 +- internal/ossl/ossl_cgo.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/init_unix.go b/init_unix.go index 5c09da86..dbf5ac44 100644 --- a/init_unix.go +++ b/init_unix.go @@ -2,7 +2,7 @@ package openssl -// #cgo LDFLAGS: -ldl -pthread +// #cgo LDFLAGS: -ldl // #include // #include import "C" diff --git a/internal/ossl/ossl_cgo.go b/internal/ossl/ossl_cgo.go index 04d2d52a..3f708d55 100644 --- a/internal/ossl/ossl_cgo.go +++ b/internal/ossl/ossl_cgo.go @@ -5,6 +5,7 @@ package ossl /* #include "ossl_extra.h" #include +#cgo linux LDFLAGS: -ldl -pthread */ import "C" import "unsafe" From cc1778e7edd7731930a7437c4537e9e9b626dd4b Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 18:00:01 +0100 Subject: [PATCH 19/20] fix call --- init.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.go b/init.go index 9a2d0316..6cff3fa5 100644 --- a/init.go +++ b/init.go @@ -26,7 +26,7 @@ func opensslInit(file string) (major, minor, patch uint, err error) { // version it contains. imajor := ossl.Go_openssl_version_major(handle) iminor := ossl.Go_openssl_version_minor(handle) - ipatch := ossl.Go_openssl_version_minor(handle) + ipatch := ossl.Go_openssl_version_patch(handle) if imajor < 0 || iminor < 0 || ipatch < 0 { return 0, 0, 0, errors.New("openssl: can't retrieve OpenSSL version") } From 437ea72cb37acc0b094799eef1bd5ddd207bce22 Mon Sep 17 00:00:00 2001 From: qmuntal Date: Thu, 5 Dec 2024 18:04:45 +0100 Subject: [PATCH 20/20] undo some changes --- cipher.go | 8 ++++---- rc4.go | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cipher.go b/cipher.go index 6f6b56bc..f2e1fece 100644 --- a/cipher.go +++ b/cipher.go @@ -178,7 +178,7 @@ func (c *evpCipher) encrypt(dst, src []byte) error { } defer ossl.EVP_CIPHER_CTX_free(enc_ctx) - if ossl.EVP_EncryptUpdate_wrapper(enc_ctx, unsafe.SliceData(dst), unsafe.SliceData(src), int32(c.blockSize)) != nil { + if ossl.EVP_EncryptUpdate_wrapper(enc_ctx, base(dst), base(src), int32(c.blockSize)) != nil { return errors.New("EncryptUpdate failed") } runtime.KeepAlive(c) @@ -207,7 +207,7 @@ func (c *evpCipher) decrypt(dst, src []byte) error { return errors.New("could not disable cipher padding") } - ossl.EVP_DecryptUpdate_wrapper(dec_ctx, unsafe.SliceData(dst), unsafe.SliceData(src), int32(c.blockSize)) + ossl.EVP_DecryptUpdate_wrapper(dec_ctx, base(dst), base(src), int32(c.blockSize)) runtime.KeepAlive(c) return nil } @@ -234,7 +234,7 @@ func (x *cipherCBC) CryptBlocks(dst, src []byte) { panic("crypto/cipher: output smaller than input") } if len(src) > 0 { - if ossl.EVP_CipherUpdate_wrapper(x.ctx, unsafe.SliceData(dst), unsafe.SliceData(src), int32(len(src))) != nil { + if ossl.EVP_CipherUpdate_wrapper(x.ctx, base(dst), base(src), int32(len(src))) != nil { panic("crypto/cipher: CipherUpdate failed") } runtime.KeepAlive(x) @@ -245,7 +245,7 @@ func (x *cipherCBC) SetIV(iv []byte) { if len(iv) != x.blockSize { panic("cipher: incorrect length IV") } - if ossl.EVP_CipherInit_ex(x.ctx, nil, nil, nil, unsafe.SliceData(iv), int32(cipherOpNone)) != nil { + if ossl.EVP_CipherInit_ex(x.ctx, nil, nil, nil, base(iv), int32(cipherOpNone)) != nil { panic("cipher: unable to initialize EVP cipher ctx") } } diff --git a/rc4.go b/rc4.go index e75bc553..18fe5038 100644 --- a/rc4.go +++ b/rc4.go @@ -4,7 +4,6 @@ package openssl import ( "runtime" - "unsafe" "github.com/golang-fips/openssl/v2/internal/ossl" ) @@ -59,7 +58,7 @@ func (c *RC4Cipher) XORKeyStream(dst, src []byte) { // which is what crypto/rc4 does. _ = dst[len(src)-1] var outLen int32 - if err := ossl.EVP_EncryptUpdate(c.ctx, unsafe.SliceData(dst), &outLen, unsafe.SliceData(src), int32(len(src))); err != nil { + if err := ossl.EVP_EncryptUpdate(c.ctx, base(dst), &outLen, base(src), int32(len(src))); err != nil { panic(err) } if int(outLen) != len(src) {