You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1142 lines
45 KiB
1142 lines
45 KiB
diff --git a/src/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go |
|
index d60fdb8..b90782a 100644 |
|
--- a/src/crypto/ecdsa/ecdsa_test.go |
|
+++ b/src/crypto/ecdsa/ecdsa_test.go |
|
@@ -323,6 +323,10 @@ func TestVectors(t *testing.T) { |
|
h.Write(msg) |
|
hashed := h.Sum(hashed[:0]) |
|
if boring.Enabled() { |
|
+ // SHA-1 signatures not supported in OpenSSL 3.0 |
|
+ if ch == crypto.SHA1 { |
|
+ expected = false |
|
+ } |
|
if HashVerify(pub, msg, r, s, ch) != expected { |
|
t.Fatalf("incorrect result on line %d", lineNo) |
|
} |
|
diff --git a/src/crypto/internal/boring/aes.go b/src/crypto/internal/boring/aes.go |
|
index 457decf..961795a 100644 |
|
--- a/src/crypto/internal/boring/aes.go |
|
+++ b/src/crypto/internal/boring/aes.go |
|
@@ -130,7 +130,11 @@ func (c *aesCipher) Decrypt(dst, src []byte) { |
|
panic("cipher: unable to initialize EVP cipher ctx") |
|
} |
|
} |
|
- |
|
+ // Workaround - padding detection is broken but we don't need it |
|
+ // since we check for full blocks |
|
+ if C._goboringcrypto_EVP_CIPHER_CTX_set_padding(c.dec_ctx, 0) != 1 { |
|
+ panic("crypto/cipher: could not disable cipher padding") |
|
+ } |
|
outlen := C.int(0) |
|
C._goboringcrypto_EVP_CipherUpdate(c.dec_ctx, (*C.uchar)(unsafe.Pointer(&dst[0])), &outlen, (*C.uchar)(unsafe.Pointer(&src[0])), C.int(aesBlockSize)) |
|
runtime.KeepAlive(c) |
|
@@ -157,6 +161,11 @@ func (x *aesCBC) CryptBlocks(dst, src []byte) { |
|
} |
|
if len(src) > 0 { |
|
outlen := C.int(0) |
|
+ // Workaround - padding detection is broken but we don't need it |
|
+ // since we check for full blocks |
|
+ if C._goboringcrypto_EVP_CIPHER_CTX_set_padding(x.ctx, 0) != 1 { |
|
+ panic("crypto/cipher: could not disable cipher padding") |
|
+ } |
|
if C._goboringcrypto_EVP_CipherUpdate( |
|
x.ctx, |
|
base(dst), &outlen, |
|
diff --git a/src/crypto/internal/boring/boring.go b/src/crypto/internal/boring/boring.go |
|
index e7ae80c..45c856b 100644 |
|
--- a/src/crypto/internal/boring/boring.go |
|
+++ b/src/crypto/internal/boring/boring.go |
|
@@ -20,7 +20,8 @@ import ( |
|
"math/big" |
|
"os" |
|
"runtime" |
|
- "strings" |
|
+ "unsafe" |
|
+ "fmt" |
|
) |
|
|
|
const ( |
|
@@ -68,8 +69,22 @@ func enableBoringFIPSMode() { |
|
} |
|
|
|
func fipsModeEnabled() bool { |
|
- return os.Getenv("GOLANG_FIPS") == "1" || |
|
- C._goboringcrypto_FIPS_mode() == fipsOn |
|
+ // Due to the way providers work in openssl 3, the FIPS methods are not |
|
+ // necessarily going to be available for us to load based on the GOLANG_FIPS |
|
+ // environment variable alone. For now, we must rely on the config to tell |
|
+ // us if the provider is configured and active. |
|
+ |
|
+ fipsConfigured := C._goboringcrypto_FIPS_mode() == fipsOn |
|
+ openSSLVersion := C._goboringcrypto_internal_OPENSSL_VERSION_NUMBER() |
|
+ if openSSLVersion >= C.ulong(0x30000000) { |
|
+ if !fipsConfigured && os.Getenv("GOLANG_FIPS") == "1" { |
|
+ panic("GOLANG_FIPS=1 specified but OpenSSL FIPS provider is not configured") |
|
+ } |
|
+ return fipsConfigured |
|
+ |
|
+ } else { |
|
+ return os.Getenv("GOLANG_FIPS") == "1" || fipsConfigured |
|
+ } |
|
} |
|
|
|
var randstub bool |
|
@@ -126,23 +141,31 @@ func PanicIfStrictFIPS(msg string) { |
|
} |
|
|
|
func NewOpenSSLError(msg string) error { |
|
- var b strings.Builder |
|
var e C.ulong |
|
|
|
- b.WriteString(msg) |
|
- b.WriteString("\nopenssl error(s):\n") |
|
+ message := fmt.Sprintf("\n%v\nopenssl error(s):", msg) |
|
|
|
for { |
|
- e = C._goboringcrypto_internal_ERR_get_error() |
|
+ var file *C.char |
|
+ var line C.int |
|
+ var fnc *C.char |
|
+ var data *C.char |
|
+ var flags C.int |
|
+ e = C._goboringcrypto_internal_ERR_get_error_all(&file, &line, &fnc, &data, &flags) |
|
if e == 0 { |
|
break |
|
} |
|
- var buf [256]byte |
|
- C._goboringcrypto_internal_ERR_error_string_n(e, base(buf[:]), 256) |
|
- b.Write(buf[:]) |
|
- b.WriteByte('\n') |
|
+ var buf [256]C.char |
|
+ C._goboringcrypto_internal_ERR_error_string_n(e, (*C.uchar)(unsafe.Pointer (&buf[0])), 256) |
|
+ message = fmt.Sprintf("%v\nfile: %v\nline: %v\nfunction: %v\nflags: %v\nerror string: %s\n", |
|
+ message, |
|
+ C.GoString(file), |
|
+ line, |
|
+ C.GoString(fnc), |
|
+ flags, |
|
+ C.GoString(&(buf[0]))) |
|
} |
|
- return errors.New(b.String()) |
|
+ return errors.New(message) |
|
} |
|
|
|
type fail string |
|
diff --git a/src/crypto/internal/boring/goopenssl.h b/src/crypto/internal/boring/goopenssl.h |
|
index 355638b..2737441 100644 |
|
--- a/src/crypto/internal/boring/goopenssl.h |
|
+++ b/src/crypto/internal/boring/goopenssl.h |
|
@@ -14,6 +14,15 @@ |
|
|
|
#include <openssl/ossl_typ.h> |
|
|
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000 |
|
+#define OPENSSL_DLSYM_CALL(handle, func) dlsym(handle, func) |
|
+#else |
|
+#define __USE_GNU |
|
+#define OPENSSL_DLSYM_CALL(handle, func) dlvsym(handle, func, "OPENSSL_3.0.0") |
|
+#endif |
|
+ |
|
+#include <dlfcn.h> |
|
+ |
|
#define unlikely(x) __builtin_expect(!!(x), 0) |
|
#define DEFINEFUNC(ret, func, args, argscall) \ |
|
typedef ret(*_goboringcrypto_PTR_##func) args; \ |
|
@@ -22,7 +31,7 @@ |
|
{ \ |
|
if (unlikely(!_g_##func)) \ |
|
{ \ |
|
- _g_##func = dlsym(handle, #func); \ |
|
+ _g_##func = OPENSSL_DLSYM_CALL(handle, #func); \ |
|
} \ |
|
return _g_##func argscall; \ |
|
} |
|
@@ -34,7 +43,7 @@ |
|
{ \ |
|
if (unlikely(!_g_internal_##func)) \ |
|
{ \ |
|
- _g_internal_##func = dlsym(handle, #func); \ |
|
+ _g_internal_##func = OPENSSL_DLSYM_CALL(handle, #func); \ |
|
} \ |
|
return _g_internal_##func argscall; \ |
|
} |
|
@@ -45,7 +54,6 @@ |
|
return func argscall; \ |
|
} |
|
|
|
-#include <dlfcn.h> |
|
|
|
static void* handle; |
|
static void* |
|
@@ -57,8 +65,10 @@ _goboringcrypto_DLOPEN_OPENSSL(void) |
|
} |
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L |
|
handle = dlopen("libcrypto.so.10", RTLD_NOW | RTLD_GLOBAL); |
|
-#else |
|
+#elif OPENSSL_VERSION_NUMBER < 0x30000000L |
|
handle = dlopen("libcrypto.so.1.1", RTLD_NOW | RTLD_GLOBAL); |
|
+#else |
|
+ handle = dlopen("libcrypto.so.3", RTLD_NOW | RTLD_GLOBAL); |
|
#endif |
|
return handle; |
|
} |
|
@@ -68,6 +78,10 @@ _goboringcrypto_DLOPEN_OPENSSL(void) |
|
|
|
DEFINEFUNCINTERNAL(int, OPENSSL_init, (void), ()) |
|
|
|
+static unsigned long _goboringcrypto_internal_OPENSSL_VERSION_NUMBER(void) { |
|
+ return OPENSSL_VERSION_NUMBER; |
|
+} |
|
+ |
|
static void |
|
_goboringcrypto_OPENSSL_setup(void) { |
|
_goboringcrypto_internal_OPENSSL_init(); |
|
@@ -76,6 +90,9 @@ _goboringcrypto_OPENSSL_setup(void) { |
|
#include <openssl/err.h> |
|
DEFINEFUNCINTERNAL(void, ERR_print_errors_fp, (FILE* fp), (fp)) |
|
DEFINEFUNCINTERNAL(unsigned long, ERR_get_error, (void), ()) |
|
+DEFINEFUNCINTERNAL(unsigned long, ERR_get_error_all, |
|
+ (const char **file, int *line, const char **func, const char **data, int *flags), |
|
+ (file, line, func, data, flags)) |
|
DEFINEFUNCINTERNAL(void, ERR_error_string_n, (unsigned long e, unsigned char *buf, size_t len), (e, buf, len)) |
|
|
|
#include <openssl/crypto.h> |
|
@@ -112,8 +129,15 @@ _goboringcrypto_CRYPTO_set_locking_callback(void (*locking_function)(int mode, i |
|
|
|
int _goboringcrypto_OPENSSL_thread_setup(void); |
|
|
|
+#if OPENSSL_VERSION_NUMBER < 0x30000000L |
|
DEFINEFUNC(int, FIPS_mode, (void), ()) |
|
DEFINEFUNC(int, FIPS_mode_set, (int r), (r)) |
|
+#else |
|
+DEFINEFUNC(int, EVP_default_properties_is_fips_enabled, (OSSL_LIB_CTX *libctx), (libctx)) |
|
+static inline int _goboringcrypto_FIPS_mode(void) { |
|
+ return _goboringcrypto_EVP_default_properties_is_fips_enabled(NULL); |
|
+} |
|
+#endif |
|
|
|
#include <openssl/rand.h> |
|
|
|
@@ -711,12 +735,9 @@ _goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(GO_EVP_PKEY_CTX* ctx, int pad) { |
|
#endif |
|
} |
|
|
|
-static inline int |
|
-_goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen) |
|
-{ |
|
- |
|
- return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l); |
|
-} |
|
+DEFINEFUNC(int, EVP_PKEY_CTX_set0_rsa_oaep_label, |
|
+ (GO_EVP_PKEY_CTX *ctx, uint8_t *l, int llen), |
|
+ (ctx, l, llen)) |
|
|
|
static inline int |
|
_goboringcrypto_EVP_PKEY_CTX_set_rsa_oaep_md(GO_EVP_PKEY_CTX *ctx, const GO_EVP_MD *md) |
|
@@ -736,6 +757,7 @@ static inline int |
|
_goboringcrypto_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { |
|
return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void *)md); |
|
} |
|
+ |
|
static inline int |
|
_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(GO_EVP_PKEY_CTX * ctx, const GO_EVP_MD *md) { |
|
return _goboringcrypto_EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, |
|
diff --git a/src/crypto/internal/boring/openssl_port_rsa.c b/src/crypto/internal/boring/openssl_port_rsa.c |
|
index 92fbb36..781975c 100644 |
|
--- a/src/crypto/internal/boring/openssl_port_rsa.c |
|
+++ b/src/crypto/internal/boring/openssl_port_rsa.c |
|
@@ -91,31 +91,40 @@ int _goboringcrypto_RSA_sign_pss_mgf1(GO_RSA *rsa, unsigned int *out_len, uint8_ |
|
|
|
if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0) |
|
goto err; |
|
- |
|
+ |
|
ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */); |
|
if (!ctx) |
|
goto err; |
|
|
|
- if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0) |
|
- goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) |
|
+ if (_goboringcrypto_EVP_PKEY_sign_init(ctx) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) |
|
+ } |
|
+ // This is moved earlier because openssl 3.0 alpha defaults |
|
+ // to sha1 in EVP_PKEY_CTRL_RSA_PADDING if unset and produces an error |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) { |
|
goto err; |
|
- |
|
+ } |
|
+ // doesnt take null anymore |
|
+ if (mgf1_md) |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) { |
|
+ goto err; |
|
+ } |
|
/* Determine buffer length */ |
|
- if (_goboringcrypto_EVP_PKEY_sign(ctx, NULL, &siglen, in, in_len) <= 0) |
|
+ if (_goboringcrypto_EVP_PKEY_sign(ctx, NULL, &siglen, in, in_len) <= 0) { |
|
goto err; |
|
- |
|
- if (max_out < siglen) |
|
+ } |
|
+ if (max_out < siglen) { |
|
goto err; |
|
- |
|
- if (_goboringcrypto_EVP_PKEY_sign(ctx, out, &siglen, in, in_len) <= 0) |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_sign(ctx, out, &siglen, in, in_len) <= 0) { |
|
goto err; |
|
+ } |
|
|
|
*out_len = siglen; |
|
ret = 1; |
|
@@ -142,23 +151,31 @@ int _goboringcrypto_RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, unsigned i |
|
|
|
if (_goboringcrypto_EVP_PKEY_set1_RSA(pkey, rsa) <= 0) |
|
goto err; |
|
- |
|
+ |
|
ctx = _goboringcrypto_EVP_PKEY_CTX_new(pkey, NULL /* no engine */); |
|
if (!ctx) |
|
goto err; |
|
|
|
- if (_goboringcrypto_EVP_PKEY_verify_init(ctx) <= 0) |
|
+ if (_goboringcrypto_EVP_PKEY_verify_init(ctx) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) |
|
- goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, salt_len) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) { |
|
goto err; |
|
- if (_goboringcrypto_EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) <= 0) |
|
+ } |
|
+ // doesnt take null anymore |
|
+ if (mgf1_md) |
|
+ if (_goboringcrypto_EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf1_md) <= 0) { |
|
+ goto err; |
|
+ } |
|
+ if (_goboringcrypto_EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) <= 0) { |
|
goto err; |
|
+ } |
|
|
|
ret = 1; |
|
|
|
diff --git a/src/crypto/internal/boring/rand.go b/src/crypto/internal/boring/rand.go |
|
index ff5c439..6047d65 100644 |
|
--- a/src/crypto/internal/boring/rand.go |
|
+++ b/src/crypto/internal/boring/rand.go |
|
@@ -20,7 +20,7 @@ func (randReader) Read(b []byte) (int, error) { |
|
// Note: RAND_bytes should never fail; the return value exists only for historical reasons. |
|
// We check it even so. |
|
if len(b) > 0 && C._goboringcrypto_RAND_bytes((*C.uint8_t)(unsafe.Pointer(&b[0])), C.size_t(len(b))) == 0 { |
|
- return 0, fail("RAND_bytes") |
|
+ return 0, NewOpenSSLError("RAND_bytes") |
|
} |
|
return len(b), nil |
|
} |
|
diff --git a/src/crypto/internal/boring/rsa.go b/src/crypto/internal/boring/rsa.go |
|
index b3a907f..b74e7a9 100644 |
|
--- a/src/crypto/internal/boring/rsa.go |
|
+++ b/src/crypto/internal/boring/rsa.go |
|
@@ -120,7 +120,9 @@ func (k *PrivateKeyRSA) withKey(f func(*C.GO_RSA) C.int) C.int { |
|
|
|
func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, |
|
padding C.int, h hash.Hash, label []byte, saltLen int, ch crypto.Hash, |
|
- init func(*C.GO_EVP_PKEY_CTX) C.int) (pkey *C.GO_EVP_PKEY, ctx *C.GO_EVP_PKEY_CTX, err error) { |
|
+ init func(*C.GO_EVP_PKEY_CTX) C.int) (_pkey *C.GO_EVP_PKEY, _ctx *C.GO_EVP_PKEY_CTX, err error) { |
|
+ var pkey *C.GO_EVP_PKEY |
|
+ var ctx *C.GO_EVP_PKEY_CTX |
|
defer func() { |
|
if err != nil { |
|
if pkey != nil { |
|
@@ -141,7 +143,7 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, |
|
if withKey(func(key *C.GO_RSA) C.int { |
|
return C._goboringcrypto_EVP_PKEY_set1_RSA(pkey, key) |
|
}) == 0 { |
|
- return nil, nil, fail("EVP_PKEY_set1_RSA") |
|
+ return nil, nil, NewOpenSSLError("EVP_PKEY_set1_RSA") |
|
} |
|
ctx = C._goboringcrypto_EVP_PKEY_CTX_new(pkey, nil) |
|
if ctx == nil { |
|
@@ -162,23 +164,12 @@ func setupRSA(withKey func(func(*C.GO_RSA) C.int) C.int, |
|
return nil, nil, NewOpenSSLError("EVP_PKEY_set_rsa_oaep_md failed") |
|
} |
|
// ctx takes ownership of label, so malloc a copy for BoringCrypto to free. |
|
- var clabel *C.uint8_t |
|
- clabel = nil |
|
- // OpenSSL 1.1.1 does not take ownership of the label if the length is zero. |
|
- // Depending on the malloc implementation, if clabel is allocated with malloc(0), |
|
- // metadata for the size-zero allocation is never cleaned up, which is a memory leak. |
|
- // As such, we must only allocate clabel if the label is of non zero length. |
|
- if len(label) > 0 { |
|
- clabel = (*C.uint8_t)(C.malloc(C.size_t(len(label)))) |
|
- if clabel == nil { |
|
- return nil, nil, fail("OPENSSL_malloc") |
|
- } |
|
- copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) |
|
+ clabel := (*C.uint8_t)(C.malloc(C.size_t(len(label)))) |
|
+ if clabel == nil { |
|
+ return nil, nil, NewOpenSSLError("OPENSSL_malloc") |
|
} |
|
- if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) != 1 { |
|
- if clabel != nil { |
|
- C.free(unsafe.Pointer(clabel)) |
|
- } |
|
+ copy((*[1 << 30]byte)(unsafe.Pointer(clabel))[:len(label)], label) |
|
+ if C._goboringcrypto_EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, clabel, C.int(len(label))) == 0 { |
|
return nil, nil, NewOpenSSLError("EVP_PKEY_CTX_set0_rsa_oaep_label failed") |
|
} |
|
} |
|
@@ -276,12 +267,13 @@ func SignRSAPSS(priv *PrivateKeyRSA, h crypto.Hash, hashed []byte, saltLen int) |
|
} |
|
var out []byte |
|
var outLen C.uint |
|
- if priv.withKey(func(key *C.GO_RSA) C.int { |
|
+ result := priv.withKey(func(key *C.GO_RSA) C.int { |
|
out = make([]byte, C._goboringcrypto_RSA_size(key)) |
|
return C._goboringcrypto_RSA_sign_pss_mgf1(key, &outLen, base(out), C.uint(len(out)), |
|
base(hashed), C.uint(len(hashed)), md, nil, C.int(saltLen)) |
|
- }) == 0 { |
|
- return nil, fail("RSA_sign_pss_mgf1") |
|
+ }) |
|
+ if result != 1 { |
|
+ return nil, NewOpenSSLError("RSA_sign_pss_mgf1: returned " + strconv.Itoa(int(result))) |
|
} |
|
|
|
return out[:outLen], nil |
|
@@ -295,11 +287,12 @@ func VerifyRSAPSS(pub *PublicKeyRSA, h crypto.Hash, hashed, sig []byte, saltLen |
|
if saltLen == 0 { |
|
saltLen = -2 // auto-recover |
|
} |
|
- if pub.withKey(func(key *C.GO_RSA) C.int { |
|
+ result := pub.withKey(func(key *C.GO_RSA) C.int { |
|
return C._goboringcrypto_RSA_verify_pss_mgf1(key, base(hashed), C.uint(len(hashed)), |
|
md, nil, C.int(saltLen), base(sig), C.uint(len(sig))) |
|
- }) == 0 { |
|
- return fail("RSA_verify_pss_mgf1") |
|
+ }) |
|
+ if result != 1 { |
|
+ return NewOpenSSLError("RSA_verify_pss_mgf1: returned " + strconv.Itoa(int(result))) |
|
} |
|
return nil |
|
} |
|
diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go |
|
index 2d425f9..ceb32d0 100644 |
|
--- a/src/crypto/rsa/pkcs1v15.go |
|
+++ b/src/crypto/rsa/pkcs1v15.go |
|
@@ -102,7 +102,7 @@ func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byt |
|
} |
|
out, err := boring.DecryptRSAPKCS1(bkey, ciphertext) |
|
if err != nil { |
|
- return nil, ErrDecryption |
|
+ return nil, err |
|
} |
|
return out, nil |
|
} |
|
diff --git a/src/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go |
|
index 3dd1ec9..60c769c 100644 |
|
--- a/src/crypto/rsa/pkcs1v15_test.go |
|
+++ b/src/crypto/rsa/pkcs1v15_test.go |
|
@@ -9,7 +9,6 @@ import ( |
|
"crypto" |
|
"crypto/internal/boring" |
|
"crypto/rand" |
|
- "crypto/sha1" |
|
"crypto/sha256" |
|
"encoding/base64" |
|
"encoding/hex" |
|
@@ -32,22 +31,22 @@ type DecryptPKCS1v15Test struct { |
|
in, out string |
|
} |
|
|
|
-// These test vectors were generated with `openssl rsautl -pkcs -encrypt` |
|
+// Test vectors for testRSA2048PrivateKey |
|
var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{ |
|
{ |
|
- "gIcUIoVkD6ATMBk/u/nlCZCCWRKdkfjCgFdo35VpRXLduiKXhNz1XupLLzTXAybEq15juc+EgY5o0DHv/nt3yg==", |
|
+ "Ppg5lRhQZ8zLMgU8jFWURwm+Oj3t1+9x8qIDZwWMlP6O1QVO4xXxHdheVnLRa0Iq+L5HTgjk/PNNkSLIMD11ERxbMD5NtXoj64qaQDkyIBXaN0FNc5Nga/Lbb+vXVYSJ5F4KIOUYaOwzgNSCMensYNz5/7TloMy2Zoqa6vsWzcU+ujfyFaNjJXC26ZM0zv/4v9Aqqb/WIsLjEgdVvplqL1jwbI8Vv/MLEpQRay3S2RHoS9PIcvGKe3Ze0nOE8rAPiRQKfAsX+zlMkw1+LDttb5Dg/vM4lGF6jTg/nmfgCb6gjWE+QpapLKuZIN3WOwG/zslKeROErPn71xAlVeHI1Q==", |
|
"x", |
|
}, |
|
{ |
|
- "Y7TOCSqofGhkRb+jaVRLzK8xw2cSo1IVES19utzv6hwvx+M8kFsoWQm5DzBeJCZTCVDPkTpavUuEbgp8hnUGDw==", |
|
+ "kjtn1z9R67b0t7RydEoXeK9GC9wWt1J47i+14alOLCuWr9aqnJxYJS+jr2Z3/TWf4qqTiEujIP5bzvM8vnU2cnJqOGUqoH5xH1+8gq9aD0RbVY0auvUxPUKI3foLoMlp6M1fTSJGiuD9DASp7BZfiMvsU1kKPrLlHpu4azOKbAfIojyyt64Dl3cIpha8FBakym1SRM2iJKKBVae3Reu58uGX9lHroJAWiIdDT4VDIGXQv9dvsViPn4hvWKls5xYtf3V5GPHyvrptsLYcqBOUXM1Wnu2SpZxKRuyz9tWA3w377XNByDMchLJeC4qxdA6ayo53ckXr0no0fU0JrRHkdg==", |
|
"testing.", |
|
}, |
|
{ |
|
- "arReP9DJtEVyV2Dg3dDp4c/PSk1O6lxkoJ8HcFupoRorBZG+7+1fDAwT1olNddFnQMjmkb8vxwmNMoTAT/BFjQ==", |
|
+ "gljV2jJNON8RwzgVezwG/ddFWPSpGHgnUgEot42vU7Kow5TMvd43f9QAJsPQd0ocT9YIp/3km+2CSWWr+5E3fWW0p2cQBxUfnsJFsNKPvQt6Ct7Bn8HzkhxLJuvIShFzQlBuph4hBuN33dWhAFFDESsZnPvU6EFJlmTHrmqY+H9cdECU4hXQ1R7Z+lHlvT8RxDNBu1fdAarRXcKrw9EeN2ZwSvVx62aXnAcAQQkijmOn9dkObgqeii/wHPI28SR/Aa/hTw1XE5DoZmDBCx6EFJ4hcY7MKAX0iSQiaxinM+IxkqiCftOnvYv737cD/vKG6llhGCCDx0Et5xYu2JWakw==", |
|
"testing.\n", |
|
}, |
|
{ |
|
- "WtaBXIoGC54+vH0NH0CHHE+dRDOsMc/6BrfFu2lEqcKL9+uDuWaf+Xj9mrbQCjjZcpQuX733zyok/jsnqe/Ftw==", |
|
+ "iJiYwVBtLhZBmYngT5u+YR5+raI33OvpShPR9arl4zSss+eK5krMANZUTrRCsw8Tho6kpyDgVohfH5V/8zX4Rtslak1peZdvnmcEkJCFk0FpnlcALRBGTCXUJEwxlSgaTz00awCjkfLzMYNCwTAlEP9QxUX2kSIABKSUw4ARwZ5jQTGCdJNl696Q/cF1JjEqsjpPbjn4UYkV3gNl0xXPiTVgfNJKZir1caEGOKfOsfbTFixvA5oANgRySxwZfoj/6dW9xIVgcq/ssmkTl8TnTKQTY0dRTNWs8+HuQxp2I4MSmAun6LYdr8pom1IazJtp1BEaSDZ+thRIQ/oMsYDJXQ==", |
|
"01234567890123456789012345678901234567890123456789012", |
|
}, |
|
} |
|
@@ -55,10 +54,10 @@ var decryptPKCS1v15Tests = []DecryptPKCS1v15Test{ |
|
func TestDecryptPKCS1v15(t *testing.T) { |
|
decryptionFuncs := []func([]byte) ([]byte, error){ |
|
func(ciphertext []byte) (plaintext []byte, err error) { |
|
- return DecryptPKCS1v15(nil, rsaPrivateKey, ciphertext) |
|
+ return DecryptPKCS1v15(nil, testRSA2048PrivateKey, ciphertext) |
|
}, |
|
func(ciphertext []byte) (plaintext []byte, err error) { |
|
- return rsaPrivateKey.Decrypt(nil, ciphertext, nil) |
|
+ return testRSA2048PrivateKey.Decrypt(nil, ciphertext, nil) |
|
}, |
|
} |
|
|
|
@@ -78,14 +77,14 @@ func TestDecryptPKCS1v15(t *testing.T) { |
|
|
|
func TestEncryptPKCS1v15(t *testing.T) { |
|
random := rand.Reader |
|
- k := (rsaPrivateKey.N.BitLen() + 7) / 8 |
|
+ k := (testRSA2048PrivateKey.N.BitLen() + 7) / 8 |
|
|
|
tryEncryptDecrypt := func(in []byte, blind bool) bool { |
|
if len(in) > k-11 { |
|
in = in[0 : k-11] |
|
} |
|
|
|
- ciphertext, err := EncryptPKCS1v15(random, &rsaPrivateKey.PublicKey, in) |
|
+ ciphertext, err := EncryptPKCS1v15(random, &testRSA2048PrivateKey.PublicKey, in) |
|
if err != nil { |
|
t.Errorf("error encrypting: %s", err) |
|
return false |
|
@@ -97,7 +96,7 @@ func TestEncryptPKCS1v15(t *testing.T) { |
|
} else { |
|
rand = random |
|
} |
|
- plaintext, err := DecryptPKCS1v15(rand, rsaPrivateKey, ciphertext) |
|
+ plaintext, err := DecryptPKCS1v15(rand, testRSA2048PrivateKey, ciphertext) |
|
if err != nil { |
|
t.Errorf("error decrypting: %s", err) |
|
return false |
|
@@ -117,22 +116,22 @@ func TestEncryptPKCS1v15(t *testing.T) { |
|
quick.Check(tryEncryptDecrypt, config) |
|
} |
|
|
|
-// These test vectors were generated with `openssl rsautl -pkcs -encrypt` |
|
+// Test vectors for testRSA2048PrivateKey |
|
var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{ |
|
{ |
|
- "e6ukkae6Gykq0fKzYwULpZehX+UPXYzMoB5mHQUDEiclRbOTqas4Y0E6nwns1BBpdvEJcilhl5zsox/6DtGsYg==", |
|
+ "cSBy/rsocfCY2L/WDP7+oyI/uk0qf3BuJvWo1VwV/DG9XLuu7J1Gb2e7hYl3kmdf6rSnoqDuVE3viOsGeq1OsW9w0uw08syTwdOp34z90qxlrrKsGjjz9XIgErqwlWvfQ5KQQb8KA29Ub7q0sqQMMQD75bUxN3P4GhtOG6kNVY33QoCIVR65vHLcqe3SlrxAfYzlOjMNwdPsNP1GGVyAZpccxOiBJSUrssAFvRJ3g62wj2xrrtneRztmOGOy8ZSiEjGNjJ4/lmJXt2GyPXapTTKeHFbyqh5Xu8PNgMxaCgtWgMqnK6CPbJOGgski9axyaxPzjKEjUcs99dJ1mTT+qw==", |
|
"1234", |
|
}, |
|
{ |
|
- "Dtis4uk/q/LQGGqGk97P59K03hkCIVFMEFZRgVWOAAhxgYpCRG0MX2adptt92l67IqMki6iVQyyt0TtX3IdtEw==", |
|
+ "lcsS8tzZSJSiaaOSQSO4pT3Je5vvrNfAVUy3Axojr4uRreMuLRTIOOmEYRM/JcWakpJelPd+EHG/aXxId8aCoBg1MkH5q8AHW3zUARhlOd91rpASVs03v5wuk0jtiQiqr0HLNyxifSEzj04VPklc6n00yuHbI+DNTATTVkxj3a5hgOECqKi2matXGcJ5FtMEPAi2V+36y2dQ+DA/tgQrhlZ4ycA2FJnjvOHRJbC6QwNzPkzbjTlCqNzq92nwWKDypVJ29CrIQ2HYXG63DOuT96gIa08hyeZEeIrAUjtb9DK1TSEF/9BDASffHevW3/CqfpRYnFSNOj2xli3wBn1Dvg==", |
|
"FAIL", |
|
}, |
|
{ |
|
- "LIyFyCYCptPxrvTxpol8F3M7ZivlMsf53zs0vHRAv+rDIh2YsHS69ePMoPMe3TkOMZ3NupiL3takPxIs1sK+dw==", |
|
+ "Bsrz5yYuevhqx1Pxx4zEsegU2aVBZ2h9ebtAgQkq3N/og0t+8O92XpPBoNH/HT2jHclh01aij1niCqdBn2/6GBN4irnVjrWQkoAV2Q5Q+gVS0ZYeTzeX/15M/iq9xeLjBPXqj5PmNYh+vbL05FyPB+CcY8MPyv7HmtDsAWRVDxQVWy6y4lmC1/VwnG5jtmAbapE+Vyty0iVb9/Q6UaaV7DVKVssEDmwnychibJ4ACcTQ18kLkB1AE73dXp1B/XHh6ExbHXoaPeaRYr2gEI0No6VBTrMrG5eVz3dub/a5MVeat9n/oU2QQ3s/Pm0FlF9n2mwgvKm/4nLjwjiTFt3ToQ==", |
|
"abcd", |
|
}, |
|
{ |
|
- "bafnobel46bKy76JzqU/RIVOH0uAYvzUtauKmIidKgM0sMlvobYVAVQPeUQ/oTGjbIZ1v/6Gyi5AO4DtHruGdw==", |
|
+ "FKynVeuuoYxonMoXWwIw3mY7KTV3yS3fe2D+h5v6FXs/0xb5PeINCEq0+Ub5LFAZcx/lIbnt4bkLZcaKDxLpBCxpvpZNdgGxP970BvE5xmOuagF47VaqCciiERTTztRjwKTu0PZ5VtcpsxiSN4axlC1NOpJnIpDsNOWUaf5G6fCCEdfZWwgxaHLbxSAy+IdUHBH+honCPPZAyGyhERdcDRGJ8a6R20MFXC18e8asHtF5VWaicaYe0fy1Mrii46WqFY8hwoSrbHOGEQkjRymM/IQvXFdxQ1vtzAFavUsr5taiVe84DvcFJ5eRZ2jpVQTdO4gBy6RyD64iNSrv8a5dqA==", |
|
"FAIL", |
|
}, |
|
} |
|
@@ -140,7 +139,7 @@ var decryptPKCS1v15SessionKeyTests = []DecryptPKCS1v15Test{ |
|
func TestEncryptPKCS1v15SessionKey(t *testing.T) { |
|
for i, test := range decryptPKCS1v15SessionKeyTests { |
|
key := []byte("FAIL") |
|
- err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, decodeBase64(test.in), key) |
|
+ err := DecryptPKCS1v15SessionKey(nil, testRSA2048PrivateKey, decodeBase64(test.in), key) |
|
if err != nil { |
|
t.Errorf("#%d error decrypting", i) |
|
} |
|
@@ -153,7 +152,7 @@ func TestEncryptPKCS1v15SessionKey(t *testing.T) { |
|
|
|
func TestEncryptPKCS1v15DecrypterSessionKey(t *testing.T) { |
|
for i, test := range decryptPKCS1v15SessionKeyTests { |
|
- plaintext, err := rsaPrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4}) |
|
+ plaintext, err := testRSA2048PrivateKey.Decrypt(rand.Reader, decodeBase64(test.in), &PKCS1v15DecryptOptions{SessionKeyLen: 4}) |
|
if err != nil { |
|
t.Fatalf("#%d: error decrypting: %s", i, err) |
|
} |
|
@@ -187,19 +186,19 @@ type signPKCS1v15Test struct { |
|
in, out string |
|
} |
|
|
|
-// These vectors have been tested with |
|
-// `openssl rsautl -verify -inkey pk -in signature | hexdump -C` |
|
-var signPKCS1v15Tests = []signPKCS1v15Test{ |
|
- {"Test.\n", "a4f3fa6ea93bcdd0c57be020c1193ecbfd6f200a3d95c409769b029578fa0e336ad9a347600e40d3ae823b8c7e6bad88cc07c1d54c3a1523cbbb6d58efc362ae"}, |
|
+// Test vector for testRSA2048PrivateKey |
|
+// generated with `openssl pkeyutl -rawin -digest sha256 -sign -inkey <key>` |
|
+ var signPKCS1v15Tests = []signPKCS1v15Test{ |
|
+ {"Test.\n", "467c3c8f16223ba09aecfe44488d6b34b3f91f11379949b1d8af31636ee8b3aa51eebb96ee11678323cb1f909af17c9d0fe4b6012078af8120474474efd1bb51765e1647369ddba6525c6608113857bb0e2aaed9ad01fe041b476b162f7d4db55bb31fa957046616ce463cecb2a66f38fa62c594d07afcc870582d545853b31fa705ab8565e4085804c32e73459720bf4e08f097843b0845116d4376231fa2472abc89b1e42462002bf70f9a1df31db6d2ab6dc52c8223798a4f57c40d6a9123b80739846d779044eac28d8c783e8ce73919f1d4a6efe8fb601b8d36c5c9b61654d6f8717d1fb9fcafa19669200900899dd08ce921a1745312eb06040a405903"}, |
|
} |
|
|
|
func TestSignPKCS1v15(t *testing.T) { |
|
for i, test := range signPKCS1v15Tests { |
|
- h := sha1.New() |
|
+ h := sha256.New() |
|
h.Write([]byte(test.in)) |
|
digest := h.Sum(nil) |
|
|
|
- s, err := SignPKCS1v15(nil, rsaPrivateKey, crypto.SHA1, digest) |
|
+ s, err := SignPKCS1v15(nil, testRSA2048PrivateKey, crypto.SHA256, digest) |
|
if err != nil { |
|
t.Errorf("#%d %s", i, err) |
|
} |
|
@@ -213,13 +212,13 @@ func TestSignPKCS1v15(t *testing.T) { |
|
|
|
func TestVerifyPKCS1v15(t *testing.T) { |
|
for i, test := range signPKCS1v15Tests { |
|
- h := sha1.New() |
|
+ h := sha256.New() |
|
h.Write([]byte(test.in)) |
|
digest := h.Sum(nil) |
|
|
|
sig, _ := hex.DecodeString(test.out) |
|
|
|
- err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, digest, sig) |
|
+ err := VerifyPKCS1v15(&testRSA2048PrivateKey.PublicKey, crypto.SHA256, digest, sig) |
|
if err != nil { |
|
t.Errorf("#%d %s", i, err) |
|
} |
|
@@ -230,7 +229,7 @@ func TestHashVerifyPKCS1v15(t *testing.T) { |
|
for i, test := range signPKCS1v15Tests { |
|
sig, _ := hex.DecodeString(test.out) |
|
|
|
- err := HashVerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA1, []byte(test.in), sig) |
|
+ err := HashVerifyPKCS1v15(&testRSA2048PrivateKey.PublicKey, crypto.SHA256, []byte(test.in), sig) |
|
if err != nil { |
|
t.Errorf("#%d %s", i, err) |
|
} |
|
@@ -273,19 +272,47 @@ func TestUnpaddedSignature(t *testing.T) { |
|
func TestShortSessionKey(t *testing.T) { |
|
// This tests that attempting to decrypt a session key where the |
|
// ciphertext is too small doesn't run outside the array bounds. |
|
- ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1}) |
|
- if err != nil { |
|
- t.Fatalf("Failed to encrypt short message: %s", err) |
|
+ var keys []*PrivateKey |
|
+ if boring.Enabled() { |
|
+ keys = GenerateTestPrivateKeys() |
|
+ } else { |
|
+ keys = []*PrivateKey{rsaPrivateKey} |
|
} |
|
|
|
- var key [32]byte |
|
- if err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, ciphertext, key[:]); err != nil { |
|
- t.Fatalf("Failed to decrypt short message: %s", err) |
|
- } |
|
+ for i, k := range keys { |
|
+ |
|
+ if k.Size() >= 256 || !boring.Enabled() { |
|
+ ciphertext, err := EncryptPKCS1v15(rand.Reader, &k.PublicKey, []byte{1}) |
|
+ if err != nil { |
|
+ t.Fatalf("Failed to encrypt short message: key: %v, %s", i, err) |
|
+ continue |
|
+ } |
|
+ |
|
+ var key [32]byte |
|
+ if err := DecryptPKCS1v15SessionKey(nil, k, ciphertext, key[:]); err != nil { |
|
+ t.Fatalf("Failed to decrypt short message: key: %v, %s", i, err) |
|
+ continue |
|
+ } |
|
+ |
|
+ for _, v := range key { |
|
+ if v != 0 { |
|
+ t.Fatal("key was modified when ciphertext was invalid") |
|
+ } |
|
+ } |
|
+ } else { |
|
+ ciphertext, err := EncryptPKCS1v15(rand.Reader, &k.PublicKey, []byte{1}) |
|
+ if err == nil { |
|
+ t.Errorf("EncryptPKCS1v15: Should reject key smaller than 2048 bits") |
|
+ } else { |
|
+ continue |
|
+ } |
|
+ |
|
+ var key [32]byte |
|
+ err = DecryptPKCS1v15SessionKey(nil, k, ciphertext, key[:]); |
|
+ if err != nil { |
|
+ t.Errorf("DecryptPKCS1v15SessionKey: Should reject key smaller than 2048 bits") |
|
+ } |
|
|
|
- for _, v := range key { |
|
- if v != 0 { |
|
- t.Fatal("key was modified when ciphertext was invalid") |
|
} |
|
} |
|
} |
|
@@ -313,6 +340,28 @@ var rsaPrivateKey = &PrivateKey{ |
|
}, |
|
} |
|
|
|
+func generateKey(size int) *PrivateKey { |
|
+ result, err := GenerateKey(rand.Reader, size) |
|
+ if err != nil { |
|
+ panic("could not generate key") |
|
+ } |
|
+ return result |
|
+} |
|
+ |
|
+func GenerateTestPrivateKeys() []*PrivateKey { |
|
+ |
|
+ keys := []*PrivateKey{ |
|
+ generateKey(128), |
|
+ generateKey(256), |
|
+ generateKey(768), |
|
+ generateKey(1024), |
|
+ generateKey(2048), |
|
+ generateKey(3072), |
|
+ generateKey(4096), |
|
+ } |
|
+ return keys |
|
+} |
|
+ |
|
func TestShortPKCS1v15Signature(t *testing.T) { |
|
pub := &PublicKey{ |
|
E: 65537, |
|
diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go |
|
index 6a5a93f..2032b4b 100644 |
|
--- a/src/crypto/rsa/pss_test.go |
|
+++ b/src/crypto/rsa/pss_test.go |
|
@@ -132,7 +132,6 @@ func TestPSSGolden(t *testing.T) { |
|
opts := &PSSOptions{ |
|
SaltLength: PSSSaltLengthEqualsHash, |
|
} |
|
- |
|
for marker := range values { |
|
switch marker { |
|
case newKeyMarker: |
|
@@ -174,18 +173,13 @@ func TestPSSOpenSSL(t *testing.T) { |
|
h.Write(hashed) |
|
hashed = h.Sum(nil) |
|
|
|
+ // Test vector for testRSA2048PrivateKey |
|
// Generated with `echo -n testing | openssl dgst -sign key.pem -sigopt rsa_padding_mode:pss -sha256 > sig` |
|
sig := []byte{ |
|
- 0x95, 0x59, 0x6f, 0xd3, 0x10, 0xa2, 0xe7, 0xa2, 0x92, 0x9d, |
|
- 0x4a, 0x07, 0x2e, 0x2b, 0x27, 0xcc, 0x06, 0xc2, 0x87, 0x2c, |
|
- 0x52, 0xf0, 0x4a, 0xcc, 0x05, 0x94, 0xf2, 0xc3, 0x2e, 0x20, |
|
- 0xd7, 0x3e, 0x66, 0x62, 0xb5, 0x95, 0x2b, 0xa3, 0x93, 0x9a, |
|
- 0x66, 0x64, 0x25, 0xe0, 0x74, 0x66, 0x8c, 0x3e, 0x92, 0xeb, |
|
- 0xc6, 0xe6, 0xc0, 0x44, 0xf3, 0xb4, 0xb4, 0x2e, 0x8c, 0x66, |
|
- 0x0a, 0x37, 0x9c, 0x69, |
|
+ 0x50, 0x97, 0xc1, 0xe2, 0x7c, 0x67, 0x99, 0x50, 0xdc, 0x5a, 0x43, 0xc6, 0xc6, 0xf2, 0xf1, 0xff, 0xcd, 0xe7, 0x66, 0xef, 0x61, 0x41, 0x5f, 0x49, 0x4f, 0xf0, 0x11, 0xfc, 0x3d, 0xa8, 0xf9, 0x3c, 0x3a, 0x8a, 0x71, 0x5c, 0xfa, 0xbc, 0x48, 0x73, 0x37, 0xec, 0x68, 0x6d, 0x6c, 0xca, 0xe, 0x30, 0x74, 0xe1, 0xbd, 0x88, 0xb6, 0x42, 0x92, 0x8d, 0x41, 0x5f, 0x7, 0x80, 0xc5, 0xef, 0xa3, 0x2e, 0x68, 0x47, 0x83, 0xb4, 0x96, 0x4c, 0x53, 0x61, 0x2c, 0xe8, 0xb8, 0x3, 0xae, 0x44, 0x5e, 0xb3, 0x44, 0x10, 0x58, 0xfd, 0x68, 0x9c, 0x33, 0xac, 0x63, 0xfe, 0x9d, 0x84, 0xab, 0x45, 0x70, 0x54, 0xc5, 0x90, 0x1e, 0x80, 0xd4, 0x31, 0x16, 0x15, 0x4b, 0x60, 0x13, 0x24, 0xa, 0xa8, 0xbc, 0xe5, 0xeb, 0xf8, 0x7d, 0x32, 0xd9, 0xcd, 0x8b, 0xef, 0x55, 0x60, 0x1, 0xa6, 0x99, 0xa2, 0xde, 0xb0, 0x68, 0xc1, 0x64, 0x8b, 0x6, 0xe6, 0x75, 0xcf, 0x2d, 0x7a, 0x8b, 0xd6, 0xa3, 0x99, 0xf1, 0xc9, 0xaf, 0x9a, 0x81, 0xe4, 0xac, 0x2e, 0x17, 0x8c, 0x49, 0xfc, 0x12, 0x79, 0xfb, 0x4a, 0xba, 0x68, 0xd8, 0xdb, 0x43, 0x6c, 0x15, 0xaf, 0xa4, 0x16, 0x2f, 0xc9, 0x1e, 0xbe, 0xef, 0xb3, 0x35, 0x14, 0x2f, 0x35, 0x41, 0x10, 0xf8, 0x32, 0xf8, 0x0, 0x5c, 0xbf, 0x77, 0xa, 0xbb, 0x77, 0x49, 0x47, 0x54, 0x7a, 0x58, 0xfd, 0xb3, 0x2c, 0x46, 0xa0, 0x5c, 0x3, 0x7a, 0xf7, 0xab, 0x77, 0xdb, 0xca, 0x9a, 0x38, 0x89, 0xb, 0x3e, 0xb0, 0x13, 0xe8, 0x16, 0xc0, 0xca, 0x29, 0xbb, 0x4a, 0x97, 0x46, 0x53, 0x59, 0x66, 0x81, 0x84, 0x6d, 0xe5, 0xda, 0x26, 0xc9, 0x83, 0xfc, 0x67, 0xd0, 0x96, 0x72, 0x81, 0x1c, 0xe0, 0x4, 0xb7, 0x0, 0xca, 0xe0, 0x4a, 0x51, 0x4e, 0x83, 0xc8, 0xeb, 0xf7, 0x6d, |
|
} |
|
|
|
- if err := VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, nil); err != nil { |
|
+ if err := VerifyPSS(&testRSA2048PrivateKey.PublicKey, hash, hashed, sig, nil); err != nil { |
|
t.Error(err) |
|
} |
|
} |
|
@@ -212,24 +206,47 @@ func TestPSSSigning(t *testing.T) { |
|
{8, 8, true}, |
|
} |
|
|
|
+ var opts PSSOptions |
|
hash := crypto.SHA1 |
|
+ keys := []*PrivateKey{rsaPrivateKey} |
|
+ if boring.Enabled() { |
|
+ hash = crypto.SHA256 |
|
+ keys = GenerateTestPrivateKeys() |
|
+ } |
|
h := hash.New() |
|
h.Write([]byte("testing")) |
|
hashed := h.Sum(nil) |
|
- var opts PSSOptions |
|
|
|
- for i, test := range saltLengthCombinations { |
|
- opts.SaltLength = test.signSaltLength |
|
- sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts) |
|
- if err != nil { |
|
- t.Errorf("#%d: error while signing: %s", i, err) |
|
- continue |
|
- } |
|
+ for _, key := range keys { |
|
+ if !boring.Enabled() || key.Size() >= 256 { |
|
+ for i, test := range saltLengthCombinations { |
|
+ opts.SaltLength = test.signSaltLength |
|
+ sig, err := SignPSS(rand.Reader, key, hash, hashed, &opts) |
|
+ if err != nil { |
|
+ t.Errorf("#%d: ALG: %v, error while signing: %s", i, hash, err) |
|
+ continue |
|
+ } |
|
+ opts.SaltLength = test.verifySaltLength |
|
+ err = VerifyPSS(&key.PublicKey, hash, hashed, sig, &opts) |
|
+ if (err == nil) != test.good { |
|
+ t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err) |
|
+ } |
|
+ } |
|
+ } else { |
|
+ for _, test := range saltLengthCombinations { |
|
+ opts.SaltLength = test.signSaltLength |
|
+ sig, err := SignPSS(rand.Reader, key, hash, hashed, &opts) |
|
+ if err == nil { |
|
+ t.Errorf("SignPSS should reject key of size: %v\n%v", key.Size() * 8, err) |
|
+ continue |
|
+ } |
|
+ opts.SaltLength = test.verifySaltLength |
|
+ err = VerifyPSS(&key.PublicKey, hash, hashed, sig, &opts) |
|
+ if (err == nil) { |
|
+ t.Errorf("VerifyPSS should reject key of size: %v\n%v", key.Size() * 8, err) |
|
+ } |
|
+ } |
|
|
|
- opts.SaltLength = test.verifySaltLength |
|
- err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts) |
|
- if (err == nil) != test.good { |
|
- t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err) |
|
} |
|
} |
|
} |
|
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go |
|
index 24e2d22..1fd5a9a 100644 |
|
--- a/src/crypto/rsa/rsa.go |
|
+++ b/src/crypto/rsa/rsa.go |
|
@@ -35,6 +35,7 @@ import ( |
|
"crypto/internal/boring" |
|
"crypto/internal/randutil" |
|
"unsafe" |
|
+ "fmt" |
|
) |
|
|
|
var bigZero = big.NewInt(0) |
|
@@ -664,7 +665,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext |
|
} |
|
out, err := boring.DecryptRSAOAEP(hash, bkey, ciphertext, label) |
|
if err != nil { |
|
- return nil, ErrDecryption |
|
+ return nil, fmt.Errorf("decryption error: %s", err) |
|
} |
|
return out, nil |
|
} |
|
diff --git a/src/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go |
|
index d9693a7..cfe020e 100644 |
|
--- a/src/crypto/rsa/rsa_test.go |
|
+++ b/src/crypto/rsa/rsa_test.go |
|
@@ -13,6 +13,7 @@ import ( |
|
"fmt" |
|
"math/big" |
|
"testing" |
|
+ |
|
) |
|
|
|
import "crypto/internal/boring" |
|
@@ -34,34 +35,42 @@ func TestKeyGeneration(t *testing.T) { |
|
} |
|
|
|
func Test3PrimeKeyGeneration(t *testing.T) { |
|
- size := 768 |
|
+ var sizes []int |
|
if testing.Short() { |
|
- size = 256 |
|
+ sizes = []int{256} |
|
+ } else { |
|
+ sizes = []int{128, 768, 1024, 2048, 3072} |
|
} |
|
+ for _, size := range sizes { |
|
|
|
- priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size) |
|
- if err != nil { |
|
- t.Errorf("failed to generate key") |
|
+ priv, err := GenerateMultiPrimeKey(rand.Reader, 3, size) |
|
+ if err != nil { |
|
+ t.Errorf("failed to generate key") |
|
+ } |
|
+ testKeyBasics(t, priv) |
|
} |
|
- testKeyBasics(t, priv) |
|
} |
|
|
|
func Test4PrimeKeyGeneration(t *testing.T) { |
|
- size := 768 |
|
+ var sizes []int |
|
if testing.Short() { |
|
- size = 256 |
|
+ sizes = []int{256} |
|
+ } else { |
|
+ sizes = []int{128, 768, 1024, 2048, 3072} |
|
} |
|
+ for _, size := range sizes { |
|
|
|
- priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size) |
|
- if err != nil { |
|
- t.Errorf("failed to generate key") |
|
+ priv, err := GenerateMultiPrimeKey(rand.Reader, 4, size) |
|
+ if err != nil { |
|
+ t.Errorf("failed to generate key") |
|
+ } |
|
+ testKeyBasics(t, priv) |
|
} |
|
- testKeyBasics(t, priv) |
|
} |
|
|
|
func TestNPrimeKeyGeneration(t *testing.T) { |
|
primeSize := 64 |
|
- maxN := 24 |
|
+ maxN := 32 |
|
if testing.Short() { |
|
primeSize = 16 |
|
maxN = 16 |
|
@@ -117,18 +126,32 @@ func testKeyBasics(t *testing.T, priv *PrivateKey) { |
|
if boring.Enabled() { |
|
// Cannot call encrypt/decrypt directly. Test via PKCS1v15. |
|
msg := []byte("hi!") |
|
- enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg) |
|
- if err != nil { |
|
- t.Errorf("EncryptPKCS1v15: %v", err) |
|
- return |
|
- } |
|
- dec, err := DecryptPKCS1v15(rand.Reader, priv, enc) |
|
- if err != nil { |
|
- t.Errorf("DecryptPKCS1v15: %v", err) |
|
- return |
|
- } |
|
- if !bytes.Equal(dec, msg) { |
|
- t.Errorf("got:%x want:%x (%+v)", dec, msg, priv) |
|
+ // Should not accept keys smaller than 2048 bits (256 bytes) |
|
+ if priv.Size() >= 256 { |
|
+ enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg) |
|
+ if err != nil { |
|
+ t.Errorf("EncryptPKCS1v15: %v", err) |
|
+ return |
|
+ } |
|
+ dec, err := DecryptPKCS1v15(rand.Reader, priv, enc) |
|
+ if err != nil { |
|
+ t.Errorf("DecryptPKCS1v15: %v", err) |
|
+ return |
|
+ } |
|
+ if !bytes.Equal(dec, msg) { |
|
+ t.Errorf("got:%x want:%x (%+v)", dec, msg, priv) |
|
+ } |
|
+ } else { |
|
+ enc, err := EncryptPKCS1v15(rand.Reader, &priv.PublicKey, msg) |
|
+ if err == nil { |
|
+ t.Errorf("EncryptPKCS1v15: Should not accept key of size %v", priv.Size() * 8) |
|
+ return |
|
+ } |
|
+ _ , err = DecryptPKCS1v15(rand.Reader, priv, enc) |
|
+ if err == nil { |
|
+ t.Errorf("DecryptPKCS1v15: Should not accept key of size %v", priv.Size() * 8) |
|
+ return |
|
+ } |
|
} |
|
return |
|
} |
|
@@ -164,6 +187,7 @@ func fromBase10(base10 string) *big.Int { |
|
} |
|
|
|
var test2048Key *PrivateKey |
|
+var testRSA2048PrivateKey *PrivateKey |
|
|
|
func init() { |
|
test2048Key = &PrivateKey{ |
|
@@ -178,6 +202,21 @@ func init() { |
|
}, |
|
} |
|
test2048Key.Precompute() |
|
+ // This is the same testRSA2048PrivateKey from src/crypto/tls/boring_test.go, |
|
+ // just formatted without using the x509 Parser |
|
+ testRSA2048PrivateKey = &PrivateKey { |
|
+ PublicKey: PublicKey{ |
|
+ N: fromBase10("20191212046465051006148469115982609963794084216822290493008497548603282433337961188011759317867632936762484431807200684727542982286641865915343951546098189846608892055894575224375729344858650310374442622904229900868894242623139807621975608166515302294530216022389036816474348374698399654955992710180316983674809047409565569027596663420090767109285120403886497729233127551307356270679924351259776100107640885071765865832767303853854517356000385050677175012549806941229051812974721510192346810990827150439838227830352248569839727388943852973737249863837089274675024496841834194785931485429238306703429257731792443735979"), |
|
+ E: 65537, |
|
+ }, |
|
+ D: fromBase10("17880854551669112566868255345124108779447961606053558991611260520405836487267781427740459393783689829925402008838157275130340717548134956040019107677074732476577915942750039777107871579671122369249613210066309031335411813988461299033587444447689322284662780986426216011635232478916424602504476935371549462113036228740820951710434375466081011497256196435741125837599218374223248197677547321257961509961401385322723627033844333644253777689603896264679633990939957571483400832267925506777396569554295752505112186882586887396943424085633026984063372469902814987050483471096892524886948283571883744403645335501920852525393"), |
|
+ Primes: []*big.Int{ |
|
+ fromBase10("135564917074042739008372452399559667250812269638554028593490636590148234941034106656615266472037321030780472224077878987192393666277731486488609490961161995141171813440923127505183021899359310251888145112092740773465142711876177808655062479870526201006500762429604105802612357839979630776094264195301632424911"), |
|
+ fromBase10("148941278335581696308445609123523329975323575697232717856977715718810138995490768513650108277383732380774181214791356462453504708304090734692215322335879527529217737837271384209093576836051031684425884921572908683147368296418243939771852059523598364231128661438022752350148969064661946939745752818523498309989"), |
|
+ }, |
|
+ } |
|
+ testRSA2048PrivateKey.Precompute() |
|
+ |
|
} |
|
|
|
func BenchmarkRSA2048Decrypt(b *testing.B) { |
|
@@ -317,6 +356,11 @@ func TestEncryptDecryptOAEP(t *testing.T) { |
|
priv.PublicKey = PublicKey{N: n, E: test.e} |
|
priv.D = d |
|
|
|
+ if boring.Enabled() && priv.PublicKey.Size() < 256 { |
|
+ t.Logf("skipping check for unsupported key less than 2048 bits") |
|
+ continue; |
|
+ } |
|
+ t.Logf("running check for supported key size") |
|
for j, message := range test.msgs { |
|
label := []byte(fmt.Sprintf("hi#%d", j)) |
|
enc, err := EncryptOAEP(sha256, rand.Reader, &priv.PublicKey, message.in, label) |
|
diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go |
|
index 94a24ff..577bc73 100644 |
|
--- a/src/crypto/tls/boring_test.go |
|
+++ b/src/crypto/tls/boring_test.go |
|
@@ -26,7 +26,7 @@ import ( |
|
func TestBoringServerProtocolVersion(t *testing.T) { |
|
test := func(name string, v uint16, msg string) { |
|
t.Run(name, func(t *testing.T) { |
|
- serverConfig := testConfig.Clone() |
|
+ serverConfig := testConfigTemplate() |
|
serverConfig.MinVersion = VersionSSL30 |
|
clientHello := &clientHelloMsg{ |
|
vers: v, |
|
@@ -108,7 +108,7 @@ func isBoringSignatureScheme(alg SignatureScheme) bool { |
|
} |
|
|
|
func TestBoringServerCipherSuites(t *testing.T) { |
|
- serverConfig := testConfig.Clone() |
|
+ serverConfig := testConfigTemplate() |
|
serverConfig.CipherSuites = allCipherSuites() |
|
serverConfig.Certificates = make([]Certificate, 1) |
|
|
|
@@ -148,7 +148,7 @@ func TestBoringServerCipherSuites(t *testing.T) { |
|
} |
|
|
|
func TestBoringServerCurves(t *testing.T) { |
|
- serverConfig := testConfig.Clone() |
|
+ serverConfig := testConfigTemplate() |
|
serverConfig.Certificates = make([]Certificate, 1) |
|
serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate} |
|
serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey |
|
@@ -204,7 +204,7 @@ func TestBoringServerSignatureAndHash(t *testing.T) { |
|
|
|
for _, sigHash := range defaultSupportedSignatureAlgorithms { |
|
t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) { |
|
- serverConfig := testConfig.Clone() |
|
+ serverConfig := testConfigTemplate() |
|
serverConfig.Certificates = make([]Certificate, 1) |
|
|
|
testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash} |
|
@@ -263,7 +263,7 @@ func TestBoringClientHello(t *testing.T) { |
|
defer c.Close() |
|
defer s.Close() |
|
|
|
- clientConfig := testConfig.Clone() |
|
+ clientConfig := testConfigTemplate() |
|
// All sorts of traps for the client to avoid. |
|
clientConfig.MinVersion = VersionSSL30 |
|
clientConfig.MaxVersion = VersionTLS13 |
|
@@ -337,12 +337,12 @@ func TestBoringCertAlgs(t *testing.T) { |
|
|
|
// client verifying server cert |
|
testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) { |
|
- clientConfig := testConfig.Clone() |
|
+ clientConfig := testConfigTemplate() |
|
clientConfig.RootCAs = pool |
|
clientConfig.InsecureSkipVerify = false |
|
clientConfig.ServerName = "example.com" |
|
|
|
- serverConfig := testConfig.Clone() |
|
+ serverConfig := testConfigTemplate() |
|
serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}} |
|
serverConfig.BuildNameToCertificate() |
|
|
|
@@ -365,11 +365,11 @@ func TestBoringCertAlgs(t *testing.T) { |
|
|
|
// server verifying client cert |
|
testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) { |
|
- clientConfig := testConfig.Clone() |
|
+ clientConfig := testConfigTemplate() |
|
clientConfig.ServerName = "example.com" |
|
clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}} |
|
|
|
- serverConfig := testConfig.Clone() |
|
+ serverConfig := testConfigTemplate() |
|
serverConfig.ClientCAs = pool |
|
serverConfig.ClientAuth = RequireAndVerifyClientCert |
|
|
|
@@ -394,8 +394,13 @@ func TestBoringCertAlgs(t *testing.T) { |
|
// exhaustive test with computed answers. |
|
r1pool := x509.NewCertPool() |
|
r1pool.AddCert(R1.cert) |
|
- testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true) |
|
- testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true) |
|
+ // openssl 3 FIPS provider fails these now without fipstls.Force() |
|
+ shouldPass := true |
|
+ if boring.Enabled() { |
|
+ shouldPass = false |
|
+ } |
|
+ testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, shouldPass) |
|
+ testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, shouldPass) |
|
fipstls.Force() |
|
testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false) |
|
testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false) |
|
@@ -458,6 +463,10 @@ func TestBoringCertAlgs(t *testing.T) { |
|
addRoot(r&1, R1) |
|
addRoot(r&2, R2) |
|
rootName = rootName[1:] // strip leading comma |
|
+ // openssl 3 FIPS provider fails these now without fipstls.Force() |
|
+ if boring.Enabled() { |
|
+ shouldVerify = shouldVerifyFIPS |
|
+ } |
|
testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify) |
|
testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify) |
|
fipstls.Force() |
|
@@ -577,6 +586,16 @@ var ( |
|
testRSA2048PrivateKey *rsa.PrivateKey |
|
) |
|
|
|
+func testConfigTemplate() *Config { |
|
+ config := testConfig.Clone() |
|
+ if boring.Enabled() { |
|
+ config.Certificates[0].Certificate = [][]byte{testRSA2048Certificate} |
|
+ config.Certificates[0].PrivateKey = testRSA2048PrivateKey |
|
+ } |
|
+ return config |
|
+ |
|
+} |
|
+ |
|
func init() { |
|
block, _ := pem.Decode([]byte(` |
|
-----BEGIN CERTIFICATE----- |
|
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go |
|
index 449379f..801a954 100644 |
|
--- a/src/crypto/x509/x509_test.go |
|
+++ b/src/crypto/x509/x509_test.go |
|
@@ -151,6 +151,7 @@ func TestPKIXMismatchPublicKeyFormat(t *testing.T) { |
|
} |
|
|
|
var testPrivateKey *rsa.PrivateKey |
|
+var testPrivateKey2048 *rsa.PrivateKey |
|
|
|
func init() { |
|
block, _ := pem.Decode([]byte(pemPrivateKey)) |
|
@@ -159,6 +160,9 @@ func init() { |
|
if testPrivateKey, err = ParsePKCS1PrivateKey(block.Bytes); err != nil { |
|
panic("Failed to parse private key: " + err.Error()) |
|
} |
|
+ if testPrivateKey2048, err = rsa.GenerateKey(rand.Reader, 2048); err != nil { |
|
+ panic("Failed to generate key: " + err.Error()) |
|
+ } |
|
} |
|
|
|
func bigFromString(s string) *big.Int { |
|
@@ -589,8 +593,9 @@ func TestCreateSelfSignedCertificate(t *testing.T) { |
|
{"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, |
|
{"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA}, |
|
{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1}, |
|
- {"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS}, |
|
- {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS}, |
|
+ // TODO: hardcode the next two keys |
|
+ {"RSAPSS/RSAPSS", &testPrivateKey2048.PublicKey, testPrivateKey2048, true, SHA256WithRSAPSS}, |
|
+ {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey2048, false, SHA256WithRSAPSS}, |
|
{"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, |
|
{"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519}, |
|
}
|
|
|