Пример #1
0
// Decrypt implements the crypto.Decrypter operation for the given key.
func (key *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) ([]byte, error) {
	switch opts := opts.(type) {
	case *rsa.PKCS1v15DecryptOptions:
		ptxt, decyptErr := key.execute(gokeyless.OpRSADecrypt, msg)

		// If opts.SessionKeyLen is set, we must perform a variation of
		// rsa.DecryptPKCS1v15SessionKey to ensure the entire operation
		// is performed in constant time regardless of padding errors.
		if l := opts.SessionKeyLen; l > 0 {
			plaintext := make([]byte, l)
			if _, err := io.ReadFull(rand, plaintext); err != nil {
				return nil, err
			}
			valid := subtle.ConstantTimeEq(int32(len(ptxt)), int32(l))
			v2 := subtle.ConstantTimeLessOrEq(l, len(ptxt))
			l2 := subtle.ConstantTimeSelect(v2, l, len(ptxt))
			subtle.ConstantTimeCopy(valid, plaintext[:l2], ptxt[:l2])
			return plaintext, nil
		}
		// Otherwise, we can just return the error like rsa.DecryptPKCS1v15.
		return ptxt, decyptErr
	default:
		return nil, errors.New("invalid options for Decrypt")
	}
}
Пример #2
0
func secureCompare(given, actual string) bool {
	if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 {
		return subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1
	}
	/* Securely compare actual to itself to keep constant time, but always return false */
	return subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 && false
}
Пример #3
0
// Decrypt implements the crypto.Decrypter operation for the given key.
func (key *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) ([]byte, error) {
	opts1v15, ok := opts.(*rsa.PKCS1v15DecryptOptions)
	if opts != nil && !ok {
		return nil, errors.New("invalid options for Decrypt")
	}

	ptxt, err := key.execute(gokeyless.OpRSADecrypt, msg)
	if err != nil {
		return nil, err
	}

	if ok {
		// If opts.SessionKeyLen is set, we must perform a variation of
		// rsa.DecryptPKCS1v15SessionKey to ensure the entire operation
		// is performed in constant time regardless of padding errors.
		if l := opts1v15.SessionKeyLen; l > 0 {
			plaintext := make([]byte, l)
			if _, err := io.ReadFull(rand, plaintext); err != nil {
				return nil, err
			}
			valid := subtle.ConstantTimeEq(int32(len(ptxt)), int32(l))
			v2 := subtle.ConstantTimeLessOrEq(l, len(ptxt))
			l2 := subtle.ConstantTimeSelect(v2, l, len(ptxt))
			subtle.ConstantTimeCopy(valid, plaintext[:l2], ptxt[:l2])
			return plaintext, nil
		}
	}
	return ptxt, nil
}
Пример #4
0
func main() {
	log.Printf("%d", subtle.ConstantTimeByteEq(43, 65))
	log.Printf("%d", subtle.ConstantTimeCompare([]byte("batman"), []byte("robin ")))

	bytes := make([]byte, 6)
	subtle.ConstantTimeCopy(1, bytes, []byte("batman"))
	log.Printf("%s", bytes)

	log.Printf("%d", subtle.ConstantTimeEq(256, 255))
	log.Printf("%d", subtle.ConstantTimeSelect(1, 2, 3))
	log.Printf("%d", subtle.ConstantTimeSelect(0, 2, 3))
}
Пример #5
0
func SecureCompare(given, actual []byte) bool {
	if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 {
		if subtle.ConstantTimeCompare(given, actual) == 1 {
			return true
		}
		return false
	}
	// Securely compare actual to itself to keep constant time, but always return false
	if subtle.ConstantTimeCompare(actual, actual) == 1 {
		return false
	}
	return false
}
Пример #6
0
// Authenticate check the user credentials.
func Authenticate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	if subtle.ConstantTimeEq(int32(len(r.FormValue("password"))), int32(len(configuration.Password))) == 0 {
		http.Redirect(w, r, "/login", http.StatusFound)
		return
	}

	if subtle.ConstantTimeCompare([]byte(r.FormValue("password")), []byte(configuration.Password)) == 0 {
		http.Redirect(w, r, "/login", http.StatusFound)
		return
	}

	sessions.GetSession(r).Set("logged", true)
	http.Redirect(w, r, "/read", http.StatusFound)
}
Пример #7
0
// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
// It returns an error if the ciphertext is the wrong length or if the
// ciphertext is greater than the public modulus. Otherwise, no error is
// returned. If the padding is valid, the resulting plaintext message is copied
// into key. Otherwise, key is unchanged. These alternatives occur in constant
// time. It is intended that the user of this function generate a random
// session key beforehand and continue the protocol with the resulting value.
// This will remove any possibility that an attacker can learn any information
// about the plaintext.
// See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
// (Crypto '98),
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
	k := (priv.N.BitLen() + 7) / 8
	if k-(len(key)+3+8) < 0 {
		err = DecryptionError{}
		return
	}

	valid, msg, err := decryptPKCS1v15(rand, priv, ciphertext)
	if err != nil {
		return
	}

	valid &= subtle.ConstantTimeEq(int32(len(msg)), int32(len(key)))
	subtle.ConstantTimeCopy(valid, key, msg)
	return
}
Пример #8
0
func SecureCompareString(given, actual string) bool {
	// The following code is incorrect:
	// return SecureCompare([]byte(given), []byte(actual))

	if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 {
		if subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1 {
			return true
		}
		return false
	}
	// Securely compare actual to itself to keep constant time, but always return false
	if subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 {
		return false
	}
	return false
}
Пример #9
0
// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS#1 v1.5.
// If rand != nil, it uses RSA blinding to avoid timing side-channel attacks.
// It returns an error if the ciphertext is the wrong length or if the
// ciphertext is greater than the public modulus. Otherwise, no error is
// returned. If the padding is valid, the resulting plaintext message is copied
// into key. Otherwise, key is unchanged. These alternatives occur in constant
// time. It is intended that the user of this function generate a random
// session key beforehand and continue the protocol with the resulting value.
// This will remove any possibility that an attacker can learn any information
// about the plaintext.
// See ``Chosen Ciphertext Attacks Against Protocols Based on the RSA
// Encryption Standard PKCS #1'', Daniel Bleichenbacher, Advances in Cryptology
// (Crypto '98).
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) (err error) {
	if err := checkPub(&priv.PublicKey); err != nil {
		return err
	}
	k := (priv.N.BitLen() + 7) / 8
	if k-(len(key)+3+8) < 0 {
		return ErrDecryption
	}

	valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
	if err != nil {
		return
	}

	if len(em) != k {
		// This should be impossible because decryptPKCS1v15 always
		// returns the full slice.
		return ErrDecryption
	}

	valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
	subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
	return
}
Пример #10
0
// IsKeySuitable returns true if the byte slice represents a valid
// secretbox key.
func KeyIsSuitable(key []byte) bool {
	return subtle.ConstantTimeEq(int32(len(key)), int32(KeySize)) == 1
}