-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathksf.go
107 lines (82 loc) · 2.76 KB
/
ksf.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// SPDX-License-Identifier: MIT
//
// Copyright (C) 2020 Daniel Bourdrez. All Rights Reserved.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree or at
// https://spdx.org/licenses/MIT.html
// Package ksf provides an interface to key stretching functions, a.k.a password key derivation functions.
package ksf
import (
cryptorand "crypto/rand"
"errors"
"fmt"
)
var errParams = errors.New("invalid amount of parameters")
// Identifier is used to specify the key stretching function to be used.
type Identifier byte
const (
// Argon2id password kdf function.
Argon2id Identifier = 1 + iota
// Scrypt password kdf function.
Scrypt
// PBKDF2Sha512 PBKDF2 password kdf function using SHA-512.
PBKDF2Sha512
// Bcrypt password kdf function.
Bcrypt
maxID
)
// Available reports whether the given kdf function is linked into the binary.
func (i Identifier) Available() bool {
return i > 0 && i < maxID
}
// Get returns a KSF with default parameters.
func (i Identifier) Get() *KSF {
if !i.Available() {
return nil
}
return &KSF{constructors[i-1]()}
}
// Harden uses default parameters for the key derivation function over the input password and salt.
func (i Identifier) Harden(password, salt []byte, length int) []byte {
return i.Get().Harden(password, salt, length)
}
// String returns the string name of the hashing function.
func (i Identifier) String() string {
return i.Get().String()
}
type constructor func() keyStretchingFunction
var constructors [maxID - 1]constructor
func (i Identifier) register(c constructor) {
constructors[i-1] = c
}
func init() {
Argon2id.register(argon2idNew)
Scrypt.register(scryptKSFNew)
PBKDF2Sha512.register(pbkdf2New)
Bcrypt.register(bcryptNew)
}
type keyStretchingFunction interface {
// Harden uses default parameters for the key derivation function over the input password and salt.
Harden(password, salt []byte, length int) []byte
// Parameterize replaces the functions parameters with the new ones. Must match the amount of parameters.
Parameterize(parameters ...int)
// String returns the string name of the function and its parameters.
String() string
// Params returns the list of internal parameters. If none was provided or modified, the recommended defaults values
// are used.
Params() []int
}
// KSF allows customisation of the underlying key stretching function.
type KSF struct {
keyStretchingFunction
}
// Salt returns random bytes of length len (wrapper for crypto/rand).
func Salt(length int) []byte {
s := make([]byte, length)
if _, err := cryptorand.Read(s); err != nil {
// We can as well not panic and try again in a loop and a counter to stop.
panic(fmt.Errorf("unexpected error in generating a salt : %w", err))
}
return s
}