scrypt: fix panic on parameters <= 0

Providing 0 as argument for r or p results in a panic:
panic: runtime error: integer divide by zero

Providing negative values for r or p returns a misleading error:
scrypt: parameters are too large

This change avoids the panic and introduces a new error
that is returned when r or p are <= 0:
scrypt: parameters must be > 0

Change-Id: I68987b27d1eedd66644d2ec9436cba364fc1d46d
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/731780
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Auto-Submit: Roland Shoemaker <roland@golang.org>
diff --git a/scrypt/scrypt.go b/scrypt/scrypt.go
index 76fa40f..b422b7d 100644
--- a/scrypt/scrypt.go
+++ b/scrypt/scrypt.go
@@ -196,6 +196,9 @@
 	if N <= 1 || N&(N-1) != 0 {
 		return nil, errors.New("scrypt: N must be > 1 and a power of 2")
 	}
+	if r <= 0 || p <= 0 {
+		return nil, errors.New("scrypt: parameters must be > 0")
+	}
 	if uint64(r)*uint64(p) >= 1<<30 || r > maxInt/128/p || r > maxInt/256 || N > maxInt/128/r {
 		return nil, errors.New("scrypt: parameters are too large")
 	}
diff --git a/scrypt/scrypt_test.go b/scrypt/scrypt_test.go
index 766ed8d..8a4637f 100644
--- a/scrypt/scrypt_test.go
+++ b/scrypt/scrypt_test.go
@@ -133,6 +133,10 @@
 	{"p", "s", 1, 1, 1, nil},                    // N == 1
 	{"p", "s", 7, 8, 1, nil},                    // N is not power of 2
 	{"p", "s", 16, maxInt / 2, maxInt / 2, nil}, // p * r too large
+	{"p", "s", 2, 0, 1, nil},                    // r too small
+	{"p", "s", 2, 1, 0, nil},                    // p too small
+	{"p", "s", 2, -1, 1, nil},                   // r is negative
+	{"p", "s", 2, 1, -1, nil},                   // p is negative
 }
 
 func TestKey(t *testing.T) {