1 /*******************************************************************************
2 
3     The core of the libgcrypt key derivation classes.
4 
5     A key derivation function is a means of deriving a secret key from a secret
6     value, for example a passphrase, using a salt and a pseudo-random function.
7 
8     Requires linking with libgcrypt:
9             -L-lgcrypt
10 
11     Copyright:
12         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
13         All rights reserved.
14 
15     License:
16         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
17         Alternatively, this file may be distributed under the terms of the Tango
18         3-Clause BSD License (see LICENSE_BSD.txt for details).
19 
20 *******************************************************************************/
21 
22 module ocean.util.cipher.gcrypt.core.KeyDerivationCore;
23 
24 import ocean.util.cipher.gcrypt.c.kdf;
25 import ocean.util.cipher.gcrypt.c.md;
26 
27 /*******************************************************************************
28 
29     Alias for the KDF algorithm
30 
31 *******************************************************************************/
32 
33 public alias gcry_kdf_algos KDF;
34 
35 /*******************************************************************************
36 
37     Alias for the hashing function
38 
39 *******************************************************************************/
40 
41 public alias gcry_md_algos Hasher;
42 
43 /*******************************************************************************
44 
45     Key derivation wrapper base class
46 
47     Params:
48         algorithm = The KDF algorithm to use
49         hasher = The pseudorandom hashing function to use
50 
51 *******************************************************************************/
52 
53 public class KeyDerivationCore ( KDF algorithm, Hasher hasher )
54 {
55     import ocean.util.cipher.gcrypt.core.Gcrypt: GcryptException;
56 
57     /***************************************************************************
58 
59         The passphrase buffer
60 
61     ***************************************************************************/
62 
63     private const(ubyte)[] passphrase;
64 
65     /***************************************************************************
66 
67         The salt buffer
68 
69     ***************************************************************************/
70 
71     private const(ubyte)[] salt;
72 
73     /***************************************************************************
74 
75         Reusable exception
76 
77     ***************************************************************************/
78 
79     private GcryptException exception;
80 
81     /***************************************************************************
82 
83         Constructor
84 
85         Params:
86             passphrase = The passphrase
87             salt = The salt
88 
89     ***************************************************************************/
90 
91     public this ( in ubyte[] passphrase, in ubyte[] salt )
92     {
93         this.passphrase = passphrase;
94         this.salt = salt;
95 
96         this.exception = new GcryptException();
97     }
98 
99     /***************************************************************************
100 
101         Derive a key using the given number of iterations, store it in the
102         given buffer. The length of the buffer must be the same as the expected
103         length of the generated key.
104 
105         Params:
106             iterations = The number of hashing iterations
107             key_buf = The buffer to store the key in
108 
109         Returns:
110             A slice to the key buffer
111 
112         Throws:
113             GcryptException on internal Gcrypt error
114 
115     ***************************************************************************/
116 
117     public ubyte[] derive ( ulong iterations, ubyte[] key_buf )
118     {
119         auto error = gcry_kdf_derive(this.passphrase.ptr, this.passphrase.length,
120             algorithm, hasher, this.salt.ptr, this.salt.length, iterations,
121             key_buf.length, key_buf.ptr);
122 
123         this.exception.throwIfGcryptError(error);
124 
125         return key_buf;
126     }
127 }