@@ -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