@@ -420,3 +420,31 @@ 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+ 	key  =  make ([]byte , cipher .KeySize ())
428+ 	iv  =  make ([]byte , cipher .IVSize ())
429+ 
430+ 	var  saltPtr , ivPtr , passwordPtr , keyPtr  * C.uchar 
431+ 	if  len (salt ) !=  0  {
432+ 		saltPtr  =  (* C .uchar )(unsafe .Pointer (& salt [0 ]))
433+ 	}
434+ 	if  len (iv ) !=  0  {
435+ 		ivPtr  =  (* C .uchar )(unsafe .Pointer (& iv [0 ]))
436+ 	}
437+ 	if  iterations  <  1  {
438+ 		return  nil , nil , errors .New ("iterations count must be 1 or greater" )
439+ 	}
440+ 	passwordSize  :=  C .int (len (password ))
441+ 	passwordPtr  =  (* C .uchar )(unsafe .Pointer (& password [0 ]))
442+ 	keyPtr  =  (* C .uchar )(unsafe .Pointer (& key [0 ]))
443+ 
444+ 	derivedKeySize  :=  C .EVP_BytesToKey (cipher .ptr , digest .ptr , saltPtr ,
445+ 		passwordPtr , passwordSize , C .int (iterations ), keyPtr , ivPtr )
446+ 	if  derivedKeySize  !=  C .int (cipher .KeySize ()) {
447+ 		return  nil , nil , errors .New ("key derivation failed" )
448+ 	}
449+ 	return  key , iv , nil 
450+ }
0 commit comments