pbkdf2.mx raw

   1  // Copyright 2012 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  // Package pbkdf2 implements the key derivation function PBKDF2 as defined in
   6  // RFC 8018 (PKCS #5 v2.1).
   7  //
   8  // A key derivation function is useful when encrypting data based on a password
   9  // or any other not-fully-random data. It uses a pseudorandom function to derive
  10  // a secure encryption key based on the password.
  11  package pbkdf2
  12  
  13  import (
  14  	"crypto/internal/fips140/pbkdf2"
  15  	"crypto/internal/fips140hash"
  16  	"crypto/internal/fips140only"
  17  	"errors"
  18  	"hash"
  19  )
  20  
  21  // Key derives a key from the password, salt and iteration count, returning a
  22  // []byte of length keyLength that can be used as cryptographic key. The key is
  23  // derived based on the method described as PBKDF2 with the HMAC variant using
  24  // the supplied hash function.
  25  //
  26  // For example, to use a HMAC-SHA-1 based PBKDF2 key derivation function, you
  27  // can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
  28  // doing:
  29  //
  30  //	dk := pbkdf2.Key(sha1.New, "some password", salt, 4096, 32)
  31  //
  32  // Remember to get a good random salt. At least 8 bytes is recommended by the
  33  // RFC.
  34  //
  35  // Using a higher iteration count will increase the cost of an exhaustive
  36  // search but will also make derivation proportionally slower.
  37  //
  38  // keyLength must be a positive integer between 1 and (2^32 - 1) * h.Size().
  39  // Setting keyLength to a value outside of this range will result in an error.
  40  func Key[Hash hash.Hash](h func() Hash, password []byte, salt []byte, iter, keyLength int) ([]byte, error) {
  41  	fh := fips140hash.UnwrapNew(h)
  42  	if fips140only.Enabled {
  43  		if keyLength < 112/8 {
  44  			return nil, errors.New("crypto/pbkdf2: use of keys shorter than 112 bits is not allowed in FIPS 140-only mode")
  45  		}
  46  		if len(salt) < 128/8 {
  47  			return nil, errors.New("crypto/pbkdf2: use of salts shorter than 128 bits is not allowed in FIPS 140-only mode")
  48  		}
  49  		if !fips140only.ApprovedHash(fh()) {
  50  			return nil, errors.New("crypto/pbkdf2: use of hash functions other than SHA-2 or SHA-3 is not allowed in FIPS 140-only mode")
  51  		}
  52  	}
  53  	return pbkdf2.Key(fh, password, salt, iter, keyLength)
  54  }
  55