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 
25 import ocean.transition;
26 import ocean.util.cipher.gcrypt.c.kdf;
27 import ocean.util.cipher.gcrypt.c.md;
28 
29 /*******************************************************************************
30 
31     Alias for the KDF algorithm
32 
33 *******************************************************************************/
34 
35 public alias gcry_kdf_algos KDF;
36 
37 /*******************************************************************************
38 
39     Alias for the hashing function
40 
41 *******************************************************************************/
42 
43 public alias gcry_md_algos Hasher;
44 
45 /*******************************************************************************
46 
47     Key derivation wrapper base class
48 
49     Params:
50         algorithm = The KDF algorithm to use
51         hasher = The pseudorandom hashing function to use
52 
53 *******************************************************************************/
54 
55 public class KeyDerivationCore ( KDF algorithm, Hasher hasher )
56 {
57     import ocean.util.cipher.gcrypt.core.Gcrypt: GcryptException;
58 
59     /***************************************************************************
60 
61         The passphrase buffer
62 
63     ***************************************************************************/
64 
65     private Const!(ubyte)[] passphrase;
66 
67     /***************************************************************************
68 
69         The salt buffer
70 
71     ***************************************************************************/
72 
73     private Const!(ubyte)[] salt;
74 
75     /***************************************************************************
76 
77         Reusable exception
78 
79     ***************************************************************************/
80 
81     private GcryptException exception;
82 
83     /***************************************************************************
84 
85         Constructor
86 
87         Params:
88             passphrase = The passphrase
89             salt = The salt
90 
91     ***************************************************************************/
92 
93     public this ( in ubyte[] passphrase, in ubyte[] salt )
94     {
95         this.passphrase = passphrase;
96         this.salt = salt;
97 
98         this.exception = new GcryptException();
99     }
100 
101     /***************************************************************************
102 
103         Derive a key using the given number of iterations, store it in the
104         given buffer. The length of the buffer must be the same as the expected
105         length of the generated key.
106 
107         Params:
108             iterations = The number of hashing iterations
109             key_buf = The buffer to store the key in
110 
111         Returns:
112             A slice to the key buffer
113 
114         Throws:
115             GcryptException on internal Gcrypt error
116 
117     ***************************************************************************/
118 
119     public ubyte[] derive ( ulong iterations, ubyte[] key_buf )
120     {
121         auto error = gcry_kdf_derive(this.passphrase.ptr, this.passphrase.length,
122             algorithm, hasher, this.salt.ptr, this.salt.length, iterations,
123             key_buf.length, key_buf.ptr);
124 
125         this.exception.throwIfGcryptError(error);
126 
127         return key_buf;
128     }
129 }