Skip to content

Commit 8f6b53d

Browse files
committed
Add binding for EVP_BytesToKey() key derivation function
1 parent 28dd155 commit 8f6b53d

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

key.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,36 @@ func GenerateRSAKeyWithExponent(bits int, exponent int) (PrivateKey, error) {
420420
})
421421
return p, nil
422422
}
423+
424+
// DeriveKey generates a key and IV from given password and salt using openssl EVP_BytesToKey()
425+
func DeriveKey(cipher *Cipher, digest *Digest, salt []byte, password []byte,
426+
iterations int) (key, iv []byte, err error) {
427+
428+
if len(salt)!=0 && len(salt)!=8 {
429+
return nil, nil, errors.New("salt size must be 0 or 8 bytes")
430+
}
431+
if iterations < 1 {
432+
return nil, nil, errors.New("iterations count must be 1 or greater")
433+
}
434+
435+
key = make([]byte, cipher.KeySize())
436+
iv = make([]byte, cipher.IVSize())
437+
438+
var saltPtr, ivPtr, passwordPtr, keyPtr *C.uchar
439+
if len(salt) != 0 {
440+
saltPtr = (*C.uchar)(unsafe.Pointer(&salt[0]))
441+
}
442+
if len(iv) != 0 {
443+
ivPtr = (*C.uchar)(unsafe.Pointer(&iv[0]))
444+
}
445+
passwordPtr = (*C.uchar)(unsafe.Pointer(&password[0]))
446+
keyPtr = (*C.uchar)(unsafe.Pointer(&key[0]))
447+
448+
derivedKeySize := C.EVP_BytesToKey(cipher.ptr, digest.ptr, saltPtr,
449+
passwordPtr, C.int(len(password)), C.int(iterations), keyPtr, ivPtr)
450+
if derivedKeySize != C.int(cipher.KeySize()) {
451+
return nil, nil, errors.New("key derivation failed")
452+
}
453+
454+
return key, iv, nil
455+
}

0 commit comments

Comments
 (0)