Skip to content

Commit

Permalink
Add binding for EVP_BytesToKey() key derivation function
Browse files Browse the repository at this point in the history
  • Loading branch information
xakep666 committed Apr 17, 2017
1 parent 28dd155 commit 8f6b53d
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions key.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,36 @@ func GenerateRSAKeyWithExponent(bits int, exponent int) (PrivateKey, error) {
})
return p, nil
}

// DeriveKey generates a key and IV from given password and salt using openssl EVP_BytesToKey()
func DeriveKey(cipher *Cipher, digest *Digest, salt []byte, password []byte,
iterations int) (key, iv []byte, err error) {

if len(salt)!=0 && len(salt)!=8 {
return nil, nil, errors.New("salt size must be 0 or 8 bytes")
}
if iterations < 1 {
return nil, nil, errors.New("iterations count must be 1 or greater")
}

key = make([]byte, cipher.KeySize())
iv = make([]byte, cipher.IVSize())

var saltPtr, ivPtr, passwordPtr, keyPtr *C.uchar
if len(salt) != 0 {
saltPtr = (*C.uchar)(unsafe.Pointer(&salt[0]))
}
if len(iv) != 0 {
ivPtr = (*C.uchar)(unsafe.Pointer(&iv[0]))
}
passwordPtr = (*C.uchar)(unsafe.Pointer(&password[0]))
keyPtr = (*C.uchar)(unsafe.Pointer(&key[0]))

derivedKeySize := C.EVP_BytesToKey(cipher.ptr, digest.ptr, saltPtr,
passwordPtr, C.int(len(password)), C.int(iterations), keyPtr, ivPtr)
if derivedKeySize != C.int(cipher.KeySize()) {
return nil, nil, errors.New("key derivation failed")
}

return key, iv, nil
}

0 comments on commit 8f6b53d

Please sign in to comment.