* Derive key to use in cipher * @param {number} cryptoScheme - cryptoScheme being used * @param {buffer} dataKey - the unencrypted key (either from the * appliance on a get or originally generated by kms in the case of a put) * @param {object} log - logger object * @par
(cryptoScheme, dataKey, log, cb)
| 68 | * @callback called with (err, derivedKey, derivedIV) |
| 69 | */ |
| 70 | static _deriveKey(cryptoScheme, dataKey, log, cb) { |
| 71 | if (cryptoScheme <= 1) { |
| 72 | /* we are not storing hashed human password. |
| 73 | * It's a random key, so 1 iteration and |
| 74 | * a fixed salt is enough for our usecase. |
| 75 | * don't change the salt, the iteration number |
| 76 | * or the digest algorithm (sha1 here) without |
| 77 | * bumping the cryptoScheme number saved in the object |
| 78 | * metadata along with the dataKey. |
| 79 | */ |
| 80 | const salt = Buffer.from('ItsTasty', 'utf8'); |
| 81 | const iterations = 1; |
| 82 | return crypto.pbkdf2( |
| 83 | dataKey, salt, iterations, |
| 84 | this._keySize(), 'sha1', (err, derivedKey) => { |
| 85 | if (err) { |
| 86 | log.error('pbkdf2 function failed on key derivation', |
| 87 | { error: err }); |
| 88 | cb(errors.InternalError); |
| 89 | return; |
| 90 | } |
| 91 | crypto.pbkdf2( |
| 92 | derivedKey, salt, iterations, |
| 93 | this._IVSize(), 'sha1', (err, derivedIV) => { |
| 94 | if (err) { |
| 95 | log.error( |
| 96 | 'pbkdf2 function failed on IV derivation', |
| 97 | { error: err }); |
| 98 | return cb(errors.InternalError); |
| 99 | } |
| 100 | // derivedKey is the actual data encryption or |
| 101 | // decryption key used in the AES ctr cipher |
| 102 | return cb(null, derivedKey, derivedIV); |
| 103 | }); |
| 104 | }); |
| 105 | } |
| 106 | log.error('Unknown cryptographic scheme', { cryptoScheme }); |
| 107 | return cb(errors.InternalError); |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * createDecipher |
no test coverage detected