...

Source file src/github.com/ProtonMail/go-crypto/openpgp/s2k/s2k_config.go

Documentation: github.com/ProtonMail/go-crypto/openpgp/s2k

     1  package s2k
     2  
     3  import "crypto"
     4  
     5  // Config collects configuration parameters for s2k key-stretching
     6  // transformations. A nil *Config is valid and results in all default
     7  // values.
     8  type Config struct {
     9  	// S2K (String to Key) mode, used for key derivation in the context of secret key encryption
    10  	// and passphrase-encrypted data. Either s2k.Argon2S2K or s2k.IteratedSaltedS2K may be used.
    11  	// If the passphrase is a high-entropy key, indicated by setting PassphraseIsHighEntropy to true,
    12  	// s2k.SaltedS2K can also be used.
    13  	// Note: Argon2 is the strongest option but not all OpenPGP implementations are compatible with it
    14  	//(pending standardisation).
    15  	// 0 (simple), 1(salted), 3(iterated), 4(argon2)
    16  	// 2(reserved) 100-110(private/experimental).
    17  	S2KMode Mode
    18  	// Only relevant if S2KMode is not set to s2k.Argon2S2K.
    19  	// Hash is the default hash function to be used. If
    20  	// nil, SHA256 is used.
    21  	Hash crypto.Hash
    22  	// Argon2 parameters for S2K (String to Key).
    23  	// Only relevant if S2KMode is set to s2k.Argon2S2K.
    24  	// If nil, default parameters are used.
    25  	// For more details on the choice of parameters, see https://tools.ietf.org/html/rfc9106#section-4.
    26  	Argon2Config *Argon2Config
    27  	// Only relevant if S2KMode is set to s2k.IteratedSaltedS2K.
    28  	// Iteration count for Iterated S2K (String to Key). It
    29  	// determines the strength of the passphrase stretching when
    30  	// the said passphrase is hashed to produce a key. S2KCount
    31  	// should be between 65536 and 65011712, inclusive. If Config
    32  	// is nil or S2KCount is 0, the value 16777216 used. Not all
    33  	// values in the above range can be represented. S2KCount will
    34  	// be rounded up to the next representable value if it cannot
    35  	// be encoded exactly. When set, it is strongly encrouraged to
    36  	// use a value that is at least 65536. See RFC 4880 Section
    37  	// 3.7.1.3.
    38  	S2KCount int
    39  	// Indicates whether the passphrase passed by the application is a
    40  	// high-entropy key (e.g. it's randomly generated or derived from
    41  	// another passphrase using a strong key derivation function).
    42  	// When true, allows the S2KMode to be s2k.SaltedS2K.
    43  	// When the passphrase is not a high-entropy key, using SaltedS2K is
    44  	// insecure, and not allowed by draft-ietf-openpgp-crypto-refresh-08.
    45  	PassphraseIsHighEntropy bool
    46  }
    47  
    48  // Argon2Config stores the Argon2 parameters
    49  // A nil *Argon2Config is valid and results in all default
    50  type Argon2Config struct {
    51  	NumberOfPasses      uint8
    52  	DegreeOfParallelism uint8
    53  	// The memory parameter for Argon2 specifies desired memory usage in kibibytes. 
    54  	// For example memory=64*1024 sets the memory cost to ~64 MB.
    55  	Memory      	    uint32 
    56  }
    57  
    58  func (c *Config) Mode() Mode {
    59  	if c == nil {
    60  		return IteratedSaltedS2K
    61  	}
    62  	return c.S2KMode
    63  }
    64  
    65  func (c *Config) hash() crypto.Hash {
    66  	if c == nil || uint(c.Hash) == 0 {
    67  		return crypto.SHA256
    68  	}
    69  
    70  	return c.Hash
    71  }
    72  
    73  func (c *Config) Argon2() *Argon2Config {
    74  	if c == nil || c.Argon2Config == nil {
    75  		return nil
    76  	}
    77  	return c.Argon2Config
    78  }
    79  
    80  // EncodedCount get encoded count
    81  func (c *Config) EncodedCount() uint8 {
    82  	if c == nil || c.S2KCount == 0 {
    83  		return 224 // The common case. Corresponding to 16777216
    84  	}
    85  
    86  	i := c.S2KCount
    87  
    88  	switch {
    89  	case i < 65536:
    90  		i = 65536
    91  	case i > 65011712:
    92  		i = 65011712
    93  	}
    94  
    95  	return encodeCount(i)
    96  }
    97  
    98  func (c *Argon2Config) Passes() uint8 {
    99  	if c == nil || c.NumberOfPasses == 0 {
   100  		return 3
   101  	}
   102  	return c.NumberOfPasses
   103  }
   104  
   105  func (c *Argon2Config) Parallelism() uint8 {
   106  	if c == nil || c.DegreeOfParallelism == 0 {
   107  		return 4
   108  	}
   109  	return c.DegreeOfParallelism
   110  }
   111  
   112  func (c *Argon2Config) EncodedMemory() uint8 {
   113  	if c == nil || c.Memory == 0 {
   114  		return 16 // 64 MiB of RAM
   115  	}
   116  
   117  	memory := c.Memory
   118  	lowerBound := uint32(c.Parallelism())*8
   119  	upperBound := uint32(2147483648)
   120  
   121  	switch {
   122  	case memory < lowerBound:
   123  		memory = lowerBound
   124  	case memory > upperBound:
   125  		memory = upperBound
   126  	}
   127  
   128  	return encodeMemory(memory, c.Parallelism())
   129  }
   130  

View as plain text