/*
* Copyright 2018 Scytl Secure Electronic Voting SA
*
* All rights reserved
*
* See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
*/
cryptolib.modules.symmetric = cryptolib.modules.symmetric || {};
/**
* Defines a symmetric secret key
*
* @namespace symmetric/secretkey
*/
cryptolib.modules.symmetric.secretkey = function(box) {
'use strict';
box.symmetric = box.symmetric || {};
box.symmetric.secretkey = {};
/**
* Allows a symmetric secret key factory to be obtained.
*
* @exports symmetric/secretkey/factory
*/
box.symmetric.secretkey.factory = {};
var policies = {
secretkey: {
encryption: {
lengthBytes: box.policies.symmetric.secretkey.encryption.lengthBytes
},
mac: {lengthBytes: box.policies.symmetric.secretkey.mac.lengthBytes}
}
};
var utils, randomFactory, exceptions, secureRandom, lengthBytes;
var f = function(box) {
utils = box.commons.utils;
exceptions = box.commons.exceptions;
randomFactory =
new box.primitives.securerandom.factory.SecureRandomFactory();
};
f.policies = {
primitives: {
secureRandom:
{provider: box.policies.symmetric.secretkey.secureRandom.provider}
}
};
cryptolib('commons', 'primitives.securerandom', f);
/**
* Validates the received length argument, in bytes.
*
* Confirms that:
*
* - the type of
lengthBytes
is number.
* lengthBytes
is an integer with a value not less than
* 1.
*
*
* @function validateParameter
* @param lengthBytes
* {number} the length, in bytes, to be validated.
*/
var validateParameter = function(lengthBytes) {
if (typeof lengthBytes !== 'number' || lengthBytes % 1 !== 0 ||
lengthBytes < 1) {
throw new exceptions.CryptoLibException(
'The given key length is not valid.');
}
};
/**
* Represents a secret key factory.
*
* @class
*/
box.symmetric.secretkey.factory.SecretKeyFactory = function() {
secureRandom = randomFactory.getCryptoRandomBytes();
};
box.symmetric.secretkey.factory.SecretKeyFactory.prototype = {
/**
* Get a CryptoSecretKeyGenerator for encryption.
*
* @function
* @returns {symmetric/secretkey.CryptoSecretKeyGenerator} a
* CryptoSecretKeyGenerator for encryption.
*/
getCryptoSecretKeyGeneratorForEncryption: function() {
lengthBytes = policies.secretkey.encryption.lengthBytes;
return this.getCryptoSecretKeyGenerator();
},
/**
* Get a CryptoSecretKeyGenerator for MAC.
*
* @function
* @returns {symmetric/secretkey.CryptoSecretKeyGenerator} a
* CryptoSecretKeyGenerator for MAC.
*/
getCryptoSecretKeyGeneratorForMac: function() {
lengthBytes = policies.secretkey.mac.lengthBytes;
return this.getCryptoSecretKeyGenerator();
},
/**
* Create a new CryptoSecretKeyGenerator.
*
* @function
* @returns {symmetric/secretkey.CryptoSecretKeyGenerator} a
* CryptoSecretKeyGenerator.
*/
getCryptoSecretKeyGenerator: function() {
return new CryptoSecretKeyGenerator(secureRandom);
}
};
/**
* Defines a Secret Key generator.
*
* @class
* @memberof symmetric/secretkey
* @param randomGenerator
* {CryptoScytlRandomBytes} a secure random bytes generator.
*/
function CryptoSecretKeyGenerator(randomGenerator) {
this.converters = new utils.Converters();
this.randomGenerator = randomGenerator;
}
CryptoSecretKeyGenerator.prototype = {
/**
* Generates a secret key.
*
* @function
* @return A secret key, as string in Base64 encoded format.
*/
generate: function() {
try {
validateParameter(lengthBytes);
var key = this.randomGenerator.nextRandom(lengthBytes);
var keyBase64 = this.converters.base64Encode(key);
return keyBase64;
} catch (error) {
throw new exceptions.CryptoLibException(
'CryptoSecretKey could not be generated.', error);
}
}
};
};