1 package org.bouncycastle.crypto.params;
2 
3 import org.bouncycastle.crypto.DerivationParameters;
4 import org.bouncycastle.util.Arrays;
5 
6 /**
7  * Parameter class for the HKDFBytesGenerator class.
8  */
9 public class HKDFParameters
10     implements DerivationParameters
11 {
12     private final byte[] ikm;
13     private final boolean skipExpand;
14     private final byte[] salt;
15     private final byte[] info;
16 
HKDFParameters(final byte[] ikm, final boolean skip, final byte[] salt, final byte[] info)17     private HKDFParameters(final byte[] ikm, final boolean skip,
18                            final byte[] salt, final byte[] info)
19     {
20         if (ikm == null)
21         {
22             throw new IllegalArgumentException(
23                 "IKM (input keying material) should not be null");
24         }
25 
26         this.ikm = Arrays.clone(ikm);
27 
28         this.skipExpand = skip;
29 
30         if (salt == null || salt.length == 0)
31         {
32             this.salt = null;
33         }
34         else
35         {
36             this.salt = Arrays.clone(salt);
37         }
38 
39         if (info == null)
40         {
41             this.info = new byte[0];
42         }
43         else
44         {
45             this.info = Arrays.clone(info);
46         }
47     }
48 
49     /**
50      * Generates parameters for HKDF, specifying both the optional salt and
51      * optional info. Step 1: Extract won't be skipped.
52      *
53      * @param ikm  the input keying material or seed
54      * @param salt the salt to use, may be null for a salt for hashLen zeros
55      * @param info the info to use, may be null for an info field of zero bytes
56      */
HKDFParameters(final byte[] ikm, final byte[] salt, final byte[] info)57     public HKDFParameters(final byte[] ikm, final byte[] salt, final byte[] info)
58     {
59         this(ikm, false, salt, info);
60     }
61 
62     /**
63      * Factory method that makes the HKDF skip the extract part of the key
64      * derivation function.
65      *
66      * @param ikm  the input keying material or seed, directly used for step 2:
67      *             Expand
68      * @param info the info to use, may be null for an info field of zero bytes
69      * @return HKDFParameters that makes the implementation skip step 1
70      */
skipExtractParameters(final byte[] ikm, final byte[] info)71     public static HKDFParameters skipExtractParameters(final byte[] ikm,
72                                                        final byte[] info)
73     {
74 
75         return new HKDFParameters(ikm, true, null, info);
76     }
77 
defaultParameters(final byte[] ikm)78     public static HKDFParameters defaultParameters(final byte[] ikm)
79     {
80         return new HKDFParameters(ikm, false, null, null);
81     }
82 
83     /**
84      * Returns the input keying material or seed.
85      *
86      * @return the keying material
87      */
getIKM()88     public byte[] getIKM()
89     {
90         return Arrays.clone(ikm);
91     }
92 
93     /**
94      * Returns if step 1: extract has to be skipped or not
95      *
96      * @return true for skipping, false for no skipping of step 1
97      */
skipExtract()98     public boolean skipExtract()
99     {
100         return skipExpand;
101     }
102 
103     /**
104      * Returns the salt, or null if the salt should be generated as a byte array
105      * of HashLen zeros.
106      *
107      * @return the salt, or null
108      */
getSalt()109     public byte[] getSalt()
110     {
111         return Arrays.clone(salt);
112     }
113 
114     /**
115      * Returns the info field, which may be empty (null is converted to empty).
116      *
117      * @return the info field, never null
118      */
getInfo()119     public byte[] getInfo()
120     {
121         return Arrays.clone(info);
122     }
123 }
124