Skip to content

Commit 9783f40

Browse files
authored
Merge pull request #119 from golang-fips/dev/dagood/empty-label
Fix RSA OAEP failure when given empty label with OpenSSL 3
2 parents 1ee02b5 + 9e1656a commit 9783f40

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

evp.go

+17-5
Original file line numberDiff line numberDiff line change
@@ -210,15 +210,27 @@ func setupEVP(withKey withKeyFunc, padding C.int,
210210
clabel = (*C.uchar)(cryptoMalloc(len(label)))
211211
copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label)
212212
}
213-
var ret C.int
213+
var err error
214214
if vMajor == 3 {
215-
ret = C.go_openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, unsafe.Pointer(clabel), C.int(len(label)))
215+
// Docs say EVP_PKEY_CTX_set0_rsa_oaep_label accepts a null label,
216+
// but it does not: https://github.com/openssl/openssl/issues/21288
217+
if len(label) == 0 {
218+
// cryptoMalloc can't create a zero-length array: use size 1.
219+
clabel = (*C.uchar)(cryptoMalloc(1))
220+
}
221+
ret := C.go_openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, unsafe.Pointer(clabel), C.int(len(label)))
222+
if ret != 1 {
223+
err = newOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed")
224+
}
216225
} else {
217-
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))
226+
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))
227+
if ret != 1 {
228+
err = newOpenSSLError("EVP_PKEY_CTX_ctrl failed")
229+
}
218230
}
219-
if ret != 1 {
231+
if err != nil {
220232
cryptoFree(unsafe.Pointer(clabel))
221-
return nil, newOpenSSLError("EVP_PKEY_CTX_ctrl failed")
233+
return nil, err
222234
}
223235
case C.GO_RSA_PKCS1_PSS_PADDING:
224236
md := cryptoHashToMD(ch)

rsa_test.go

+23
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,29 @@ func TestEncryptDecryptOAEP(t *testing.T) {
5757
}
5858
}
5959

60+
func TestEncryptDecryptOAEP_EmptyLabel(t *testing.T) {
61+
sha256 := openssl.NewSHA256()
62+
msg := []byte("hi!")
63+
label := []byte("")
64+
priv, pub := newRSAKey(t, 2048)
65+
enc, err := openssl.EncryptRSAOAEP(sha256, nil, pub, msg, label)
66+
if err != nil {
67+
t.Fatal(err)
68+
}
69+
dec, err := openssl.DecryptRSAOAEP(sha256, nil, priv, enc, label)
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
if !bytes.Equal(dec, msg) {
74+
t.Errorf("got:%x want:%x", dec, msg)
75+
}
76+
sha1 := openssl.NewSHA1()
77+
_, err = openssl.DecryptRSAOAEP(sha1, nil, priv, enc, label)
78+
if err == nil {
79+
t.Error("decrypt failure expected due to hash mismatch")
80+
}
81+
}
82+
6083
func TestEncryptDecryptOAEP_WithMGF1Hash(t *testing.T) {
6184
sha1 := openssl.NewSHA1()
6285
sha256 := openssl.NewSHA256()

0 commit comments

Comments
 (0)