Skip to content

Commit

Permalink
Fix raw key wrappers: len can't be discarded
Browse files Browse the repository at this point in the history
  • Loading branch information
dagood committed Nov 8, 2023
1 parent 50bdc9a commit 31c3fb2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 22 deletions.
16 changes: 8 additions & 8 deletions ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,12 +145,12 @@ func NewPrivateKeyEd25519FromSeed(seed []byte) (*PrivateKeyEd25519, error) {
}

func extractPKEYPubEd25519(pkey C.GO_EVP_PKEY_PTR, pub []byte) error {
pubSize := C.size_t(publicKeySizeEd25519)
if C.go_openssl_EVP_PKEY_get_raw_public_key_wrapper(pkey, base(pub), pubSize) != 1 {
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")
}
if pubSize != publicKeySizeEd25519 {
return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(pubSize)))
if r.len != publicKeySizeEd25519 {
return errors.New("ed25519: bad public key length: " + strconv.Itoa(int(r.len)))
}
return nil
}
Expand All @@ -159,12 +159,12 @@ func extractPKEYPrivEd25519(pkey C.GO_EVP_PKEY_PTR, priv []byte) error {
if err := extractPKEYPubEd25519(pkey, priv[seedSizeEd25519:]); err != nil {
return err
}
privSize := C.size_t(seedSizeEd25519)
if C.go_openssl_EVP_PKEY_get_raw_private_key_wrapper(pkey, base(priv), privSize) != 1 {
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")
}
if privSize != seedSizeEd25519 {
return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(privSize)))
if r.len != seedSizeEd25519 {
return errors.New("ed25519: bad private key length: " + strconv.Itoa(int(r.len)))
}
return nil
}
Expand Down
37 changes: 23 additions & 14 deletions goopenssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,8 @@ go_hash_sum(GO_EVP_MD_CTX_PTR ctx, GO_EVP_MD_CTX_PTR ctx2, unsigned char *out)
return go_openssl_EVP_DigestFinal(ctx2, out, NULL);
}

// These wrappers allocate length variables on the C stack to avoid having to pass a pointer from Go, which would escape to the heap.
// 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)
{
Expand All @@ -106,18 +105,6 @@ go_openssl_EVP_CipherUpdate_wrapper(GO_EVP_CIPHER_CTX_PTR ctx, unsigned char *ou
return go_openssl_EVP_CipherUpdate(ctx, out, &len, in, in_len);
}

static inline int
go_openssl_EVP_PKEY_get_raw_public_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *pub, size_t len)
{
return go_openssl_EVP_PKEY_get_raw_public_key(pkey, pub, &len);
}

static inline int
go_openssl_EVP_PKEY_get_raw_private_key_wrapper(const GO_EVP_PKEY_PTR pkey, unsigned char *priv, size_t len)
{
return go_openssl_EVP_PKEY_get_raw_private_key(pkey, priv, &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.

Expand All @@ -135,6 +122,28 @@ go_openssl_EVP_PKEY_derive_wrapper(GO_EVP_PKEY_CTX_PTR ctx, unsigned char *key,
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;
Expand Down

0 comments on commit 31c3fb2

Please sign in to comment.