1package argon2 2 3// #cgo pkg-config: libargon2 4// #include <argon2.h> 5// #include "wrapper.h" 6import "C" 7 8// Context represents a structure that holds all static configuration values, 9// used to parameterize an Argon2 hash function. 10type Context struct { 11 Iterations int // number of iterations (t_cost) 12 Memory int // memory usage in KiB (m_cost) 13 Parallelism int // number of parallel threads 14 HashLen int // desired hash output length 15 Mode int // ModeArgon2d, ModeArgon2i, or ModeArgon2id 16 Version int // Version10 or Version13 (aka VersionDefault) 17 Secret []byte // optional (not used by default) 18 AssociatedData []byte // optional (not used by default) 19 Flags int // optional (default is FlagDefault) 20} 21 22// NewContext initializes a new Argon2 context with reasonable defaults. 23// allows the mode to be set as an optional paramter 24func NewContext(mode ...int) *Context { 25 context := &Context{ 26 Iterations: 3, 27 Memory: 1 << 12, // 4 MiB 28 Parallelism: 1, 29 HashLen: 32, 30 Mode: ModeArgon2i, 31 Version: VersionDefault, 32 } 33 if len(mode) >= 1 { 34 context.Mode = mode[0] 35 } 36 return context 37} 38 39// hash password and salt 40func (ctx *Context) hash(password []byte, salt []byte) ([]byte, error) { 41 42 if len(password) == 0 { 43 return nil, ErrPassword 44 } 45 if len(salt) == 0 { 46 return nil, ErrSalt 47 } 48 49 hash := make([]byte, ctx.HashLen) 50 51 // optional secret 52 secret := (*C.uint8_t)(nil) 53 if len(ctx.Secret) > 0 { 54 secret = (*C.uint8_t)(&ctx.Secret[0]) 55 } 56 57 // optional associated data 58 associatedData := (*C.uint8_t)(nil) 59 if len(ctx.AssociatedData) > 0 { 60 associatedData = (*C.uint8_t)(&ctx.AssociatedData[0]) 61 } 62 63 // optional flags 64 flags := FlagDefault 65 if ctx.Flags != 0 { 66 flags = ctx.Flags 67 } 68 69 // ensure version has a default 70 version := VersionDefault 71 if ctx.Version != 0 { 72 version = ctx.Version 73 } 74 75 // wrapper to overcome go pointer passing limitations 76 result := C.argon2_wrapper( 77 (*C.uint8_t)(&hash[0]), C.uint32_t(ctx.HashLen), 78 (*C.uint8_t)(&password[0]), C.uint32_t(len(password)), 79 (*C.uint8_t)(&salt[0]), C.uint32_t(len(salt)), 80 secret, C.uint32_t(len(ctx.Secret)), 81 associatedData, C.uint32_t(len(ctx.AssociatedData)), 82 C.uint32_t(ctx.Iterations), 83 C.uint32_t(ctx.Memory), 84 C.uint32_t(ctx.Parallelism), 85 C.uint32_t(ctx.Parallelism), 86 C.uint32_t(version), 87 nil, nil, 88 C.uint32_t(flags), 89 C.argon2_type(ctx.Mode)) 90 91 if result != C.ARGON2_OK { 92 return nil, Error(result) 93 } 94 95 return hash, nil 96} 97