cryptolib.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*
  2. * Copyright 2018 Scytl Secure Electronic Voting SA
  3. *
  4. * All rights reserved
  5. *
  6. * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
  7. */
  8. /**
  9. * @global
  10. * @description This object describes the configuration scheme for this
  11. * cryptographic library. The following modules are considered:
  12. * <ul>
  13. * <li> Asymmetric
  14. * <li> Primitives
  15. * <li> Stores
  16. * <li> Symmetric
  17. * <li> Digital Envelope
  18. * </ul>
  19. * @readonly
  20. * @property {object} asymmetric.keypair - Policies for generating keypairs.
  21. * @property {object} asymmetric.keypair.encryption - Policies for generating
  22. * encryption keypairs.
  23. * @property {object} asymmetric.keypair.encryption.algorithm - Algorithm.
  24. * @property {string} asymmetric.keypair.encryption.algorithm.RSA - RSA
  25. * algorithm.
  26. * @property {object} asymmetric.keypair.encryption.provider - Provider.
  27. * @property {string} asymmetric.keypair.encryption.provider.FORGE - Forge
  28. * provider.
  29. * @property {object} asymmetric.keypair.encryption.keyLength - Key length.
  30. * @property {number} asymmetric.keypair.encryption.keyLength.KL_2048 - 2048
  31. * bits.
  32. * @property {number} asymmetric.keypair.encryption.keyLength.KL_3072 - 3072
  33. * bits.
  34. * @property {number} asymmetric.keypair.encryption.keyLength.KL_4096 - 4096
  35. * bits.
  36. * @property {object} asymmetric.keypair.encryption.publicExponent - Public
  37. * exponent for generating encryption keypairs.
  38. * @property {number} asymmetric.keypair.encryption.publicExponent.F4 - 65537.
  39. *
  40. * @property {object} asymmetric.signer - Policies for signing and verifying
  41. * data.
  42. * @property {object} asymmetric.signer.algorithm - Algorithm.
  43. * @property {string} asymmetric.signer.algorithm.RSA - RSA algorithm.
  44. * @property {object} asymmetric.signer.provider - Provider.
  45. * @property {string} asymmetric.signer.provider.FORGE - Forge provider.
  46. * @property {object} asymmetric.signer.hash - Hash algorithm.
  47. * @property {string} asymmetric.signer.hash.SHA256 - SHA-256 algorithm.
  48. * @property {object} asymmetric.signer.padding - Padding scheme.
  49. * @property {object} asymmetric.signer.padding.PSS - PSS padding scheme.
  50. * @property {string} asymmetric.signer.padding.PSS.name - PSS.
  51. * @property {object} asymmetric.signer.padding.PSS.hash - Hash for the PSS
  52. * padding scheme.
  53. * @property {string} asymmetric.signer.padding.PSS.hash.SHA256 - SHA-256
  54. * algorithm.
  55. * @property {object} asymmetric.signer.padding.PSS.mask - Mask generating
  56. * function for the PSS padding scheme.
  57. * @property {object} asymmetric.signer.padding.PSS.mask.MGF1 - MGF1 for the PSS
  58. * padding scheme.
  59. * @property {string} asymmetric.signer.padding.PSS.mask.MGF1.name - MGF1.
  60. * @property {object} asymmetric.signer.padding.PSS.mask.MGF1.hash - Hash
  61. * algorithm for the MGF1 for the PSS padding scheme.
  62. * @property {string} asymmetric.signer.padding.PSS.mask.MGF1.hash.SHA256 -
  63. * SHA-256 algorithm.
  64. * @property {object} asymmetric.signer.padding.PSS.saltLengthBytes - Salt
  65. * length for the PSS padding scheme.
  66. * @property {number} asymmetric.signer.padding.PSS.saltLengthBytes.SL_32 - 32
  67. * bytes.
  68. * @property {object} asymmetric.signer.publicExponent - Public exponent.
  69. * @property {number} asymmetric.signer.publicExponent.F4 - 65537.
  70. * @property {object} primitives.securerandom - Policies for generating
  71. * securerandom.
  72. * @property {object} primitives.securerandom.provider - Provider.
  73. * @property {string} primitives.securerandom.provider.SCYTL - Scytl provider.
  74. * @property {object} primitives.messagedigest - Policies for generating message
  75. * digests.
  76. * @property {object} primitives.messagedigest.algorithm - Algorithm.
  77. * @property {string} primitives.messagedigest.algorithm.SHA256 - SHA-256
  78. * algorithm.
  79. * @property {object} primitives.messagedigest.provider - Provider.
  80. * @property {string} primitives.messagedigest.provider.FORGE - Forge provider.
  81. * @property {object} symmetric.secretkey - Policies to generate secret keys.
  82. * @property {number} symmetric.secretkey.length - 128 bits.
  83. * @property {object} symmetric.cipher - Policies to encrypt and decrypt
  84. * symmetrically.
  85. * @property {object} symmetric.cipher.algorithm - Algorithm.
  86. * @property {object} symmetric.cipher.algorithm.AES128_GCM - AES128-GCM
  87. * algorithm.
  88. * @property {string} symmetric.cipher.algorithm.AES128_GCM.name - AES128-GCM.
  89. * @property {number} symmetric.cipher.algorithm.AES128_GCM.keyLengthBytes - 16
  90. * bytes.
  91. * @property {number} symmetric.cipher.algorithm.AES128_GCM.tagLengthBytes - 16
  92. * bytes.
  93. * @property {object} symmetric.cipher.provider - Provider.
  94. * @property {object} symmetric.cipher.provider.FORGE - Forge provider.
  95. * @property {object} symmetric.cipher.initializationVectorLengthBytes -
  96. * Initialization vector length.
  97. * @property {number} symmetric.cipher.initializationVectorLengthBytes.IV_12 -
  98. * 12 bytes.
  99. */
  100. var Config = {
  101. homomorphic: {cipher: {secureRandom: {provider: {SCYTL: 'Scytl'}}}},
  102. asymmetric: {
  103. keypair: {
  104. encryption: {
  105. algorithm: {RSA: 'RSA'},
  106. provider: {FORGE: 'Forge'},
  107. keyLength: {KL_2048: 2048, KL_3072: 3072, KL_4096: 4096},
  108. publicExponent: {F4: 65537}
  109. },
  110. secureRandom: {provider: {SCYTL: 'Scytl'}}
  111. },
  112. signer: {
  113. algorithm: {RSA: 'RSA'},
  114. provider: {FORGE: 'Forge'},
  115. hash: {SHA256: 'SHA256'},
  116. padding: {
  117. PSS: {
  118. name: 'PSS',
  119. hash: {SHA256: 'SHA256'},
  120. mask: {MGF1: {name: 'MGF1', hash: {SHA256: 'SHA256'}}},
  121. saltLengthBytes: {SL_32: 32}
  122. }
  123. },
  124. publicExponent: {F4: 65537},
  125. secureRandom: {provider: {SCYTL: 'Scytl'}}
  126. },
  127. cipher: {
  128. algorithm: {
  129. RSA_OAEP: {
  130. name: 'RSA-OAEP',
  131. hash: 'SHA256',
  132. mask: {MGF1: {name: 'MGF1', hash: 'SHA1'}}
  133. },
  134. RSA_KEM: {
  135. name: 'RSA-KEM',
  136. secretKeyLengthBytes: {KL_16: 16, KL_24: 24, KL_32: 32},
  137. ivLengthBytes: {IVL_12: 12, IVL_16: 16, IVL_32: 32, IVL_64: 64},
  138. tagLengthBytes: {TL_12: 12, TL_16: 16, TL_32: 32, TL_64: 64},
  139. deriver: {
  140. name: {KDF1: 'kdf1', KDF2: 'kdf2', MGF1: 'mgf1'},
  141. messagedigest: {algorithm: {SHA256: 'SHA256'}}
  142. },
  143. cipher: {AESGCM: 'AES-GCM'}
  144. }
  145. },
  146. provider: {FORGE: 'Forge'},
  147. secureRandom: {provider: {SCYTL: 'Scytl'}}
  148. }
  149. },
  150. primitives: {
  151. secureRandom: {provider: {SCYTL: 'Scytl'}},
  152. messagedigest: {
  153. algorithm: {SHA256: 'SHA256', SHA512_224: 'SHA512/224'},
  154. provider: {FORGE: 'Forge'}
  155. },
  156. derivation: {
  157. pbkdf: {
  158. provider: {FORGE: 'Forge'},
  159. hash: {SHA256: 'SHA256'},
  160. saltLengthBytes: {SL_20: 20, SL_32: 32},
  161. keyLengthBytes: {KL_16: 16, KL_32: 32},
  162. iterations: {
  163. I_1: 1,
  164. I_8000: 8000,
  165. I_16000: 16000,
  166. I_32000: 32000,
  167. I_64000: 64000
  168. }
  169. }
  170. }
  171. },
  172. stores: {},
  173. symmetric: {
  174. secretkey: {
  175. encryption: {lengthBytes: {SK_16: 16}},
  176. mac: {lengthBytes: {SK_32: 32}},
  177. secureRandom: {provider: {SCYTL: 'Scytl'}}
  178. },
  179. cipher: {
  180. provider: {FORGE: 'Forge'},
  181. algorithm: {
  182. AES128_GCM: {name: 'AES-GCM', keyLengthBytes: 16, tagLengthBytes: 16}
  183. },
  184. initializationVectorLengthBytes: {IV_12: 12},
  185. secureRandom: {provider: {SCYTL: 'Scytl'}}
  186. },
  187. mac: {hash: {SHA256: 'SHA256'}, provider: {FORGE: 'Forge'}}
  188. },
  189. proofs: {
  190. secureRandom: {provider: {SCYTL: 'Scytl'}},
  191. messagedigest: {
  192. algorithm: {SHA256: 'SHA256', SHA512_224: 'SHA512/224'},
  193. provider: {FORGE: 'Forge'}
  194. },
  195. charset: {UTF8: 'UTF-8'}
  196. },
  197. digitalenvelope: {
  198. symmetric: {
  199. secretkey: {
  200. encryption: {lengthBytes: {SK_16: 16}},
  201. mac: {lengthBytes: {SK_32: 32}},
  202. secureRandom: {provider: {SCYTL: 'Scytl'}}
  203. },
  204. cipher: {
  205. provider: {FORGE: 'Forge'},
  206. algorithm: {
  207. AES128_GCM:
  208. {name: 'AES-GCM', keyLengthBytes: 16, tagLengthBytes: 16}
  209. },
  210. initializationVectorLengthBytes: {IV_12: 12},
  211. secureRandom: {provider: {SCYTL: 'Scytl'}}
  212. },
  213. mac: {hash: {SHA256: 'SHA256'}, provider: {FORGE: 'Forge'}}
  214. },
  215. asymmetric: {
  216. cipher: {
  217. algorithm: {
  218. RSA_OAEP: {
  219. name: 'RSA-OAEP',
  220. hash: 'SHA256',
  221. mask: {MGF1: {name: 'MGF1', hash: 'SHA1'}}
  222. },
  223. RSA_KEM: {
  224. name: 'RSA-KEM',
  225. secretKeyLengthBytes: {KL_16: 16, KL_24: 24, KL_32: 32},
  226. ivLengthBytes: {IVL_12: 12, IVL_16: 16, IVL_32: 32, IVL_64: 64},
  227. tagLengthBytes: {TL_12: 12, TL_16: 16, TL_32: 32, TL_64: 64},
  228. deriver: {
  229. name: {KDF1: 'kdf1', KDF2: 'kdf2', MGF1: 'mgf1'},
  230. messagedigest: {algorithm: {SHA256: 'SHA256'}}
  231. },
  232. cipher: {AESGCM: 'AES-GCM'}
  233. }
  234. },
  235. provider: {FORGE: 'Forge'},
  236. secureRandom: {provider: {SCYTL: 'Scytl'}}
  237. }
  238. }
  239. }
  240. };
  241. if (Object.freeze) {
  242. /**
  243. * Freezes an object and all its contents.
  244. * @param {Object} target the object to freeze.
  245. */
  246. var recursiveFreeze = function(target) {
  247. 'use strict';
  248. // Get all property names
  249. var propNames = Object.getOwnPropertyNames(target);
  250. // Freeze the object's properties.
  251. propNames.forEach(function(name) {
  252. var property = target[name];
  253. // Freeze the properties' properties.
  254. if (typeof property === 'object' && property !== null) {
  255. recursiveFreeze(property);
  256. }
  257. });
  258. // Freeze the object itself.
  259. return Object.freeze(target);
  260. };
  261. // Lock down the configuration
  262. recursiveFreeze(Config);
  263. }
  264. var cryptolibPolicies;
  265. /**
  266. * @global
  267. * @function cryptolib
  268. *
  269. * @description Core of the library, this module is used to sandbox the
  270. * requested modules.
  271. *
  272. * @example // how to load all modules cryptolib('*', function(box) { // any
  273. * module can be used from here. //
  274. * box.examplemodule.service.getExample(); });
  275. *
  276. *
  277. * @param modules
  278. * {...modules} modules to be loaded. '*' or none to load all the
  279. * modules.
  280. * @param function
  281. * {cryptolibSandbox} a closure for the cryptolib object.
  282. * @tutorial workers
  283. */
  284. function cryptolib() {
  285. 'use strict';
  286. /* Class to keep the references to polices and prng. */
  287. function Cryptolib(modules, callback) {
  288. function getAllModules(parent) {
  289. var modules = [];
  290. for (var module in parent) {
  291. if (parent.hasOwnProperty(module)) {
  292. modules.push(module);
  293. }
  294. }
  295. return modules;
  296. }
  297. function loadModules(box, modules, parentModule) {
  298. if (!modules || modules.toString() === '*'.toString()) {
  299. modules = getAllModules(parentModule);
  300. }
  301. for (var i = 0; i < modules.length; i += 1) {
  302. var firstDotIndex = modules[i].indexOf('.');
  303. if (firstDotIndex > -1) {
  304. var subModule = modules[i].substr(firstDotIndex + 1);
  305. var root = modules[i].substr(0, firstDotIndex);
  306. loadModules(box, [subModule], parentModule[root]);
  307. } else if (typeof parentModule[modules[i]] === 'function') {
  308. parentModule[modules[i]](box);
  309. } else if (typeof parentModule[modules[i]] === 'object') {
  310. loadModules(box, '*', parentModule[modules[i]]);
  311. }
  312. }
  313. }
  314. this.policies = callback.policies || cryptolibPolicies;
  315. cryptolibPolicies = cryptolibPolicies || this.policies;
  316. this.prng = callback.prng || cryptoPRNG.getPRNG();
  317. loadModules(this, modules, cryptolib.modules);
  318. callback(this);
  319. }
  320. Cryptolib.prototype = {
  321. getKeys: function(obj) {
  322. var keys = [];
  323. for (var key in obj) {
  324. if (typeof key !== 'undefined') {
  325. keys.push(key);
  326. }
  327. }
  328. return keys;
  329. },
  330. getModuleNames: function() {
  331. var moduleNames = '';
  332. for (var module in cryptolib.modules) {
  333. if (typeof module !== 'undefined') {
  334. if (moduleNames.length > 0) {
  335. moduleNames += ', ';
  336. }
  337. moduleNames += module;
  338. }
  339. }
  340. return '[' + moduleNames + ']';
  341. },
  342. forge: forge, // redefines forge global variable
  343. sjcl: sjcl, // redefines sjcl global variable
  344. // Constants.
  345. /** @constant */
  346. NUMBER_OF_BITS_PER_BYTE: 8,
  347. /** @constant */
  348. MAXIMUM_LENGTH_TO_GENERATE_DATA: 512,
  349. /** @constant */
  350. BASE_2_RADIX: 2,
  351. /** @constant */
  352. BASE_10_RADIX: 10,
  353. /** @constant */
  354. BASE_16_RADIX: 16,
  355. /** @constant */
  356. EPOCH_TIME_LENGTH: 10,
  357. /** @constant */
  358. RSA_LINE_LENGTH: 64,
  359. /** @constant */
  360. SHA_256_LENGTH: 32,
  361. /** @constant */
  362. HMAC_SHA256_KEY_LENGTH: 32,
  363. /** @constant */
  364. AES_KEY_LENGTH: 16,
  365. /** @constant */
  366. AES_CBC_IV_LENGTH: 16,
  367. /** @constant */
  368. DES3_KEY_LENGTH: 24,
  369. /** @constant */
  370. DES3_CBC_IV_LENGTH: 8,
  371. EQUALS: ' = ',
  372. NEWLINE: '\n',
  373. CRYPTO_SPEC_DELIM: '/',
  374. /** @constant */
  375. SHA_256: 'SHA256',
  376. /** @constant */
  377. RSA_ECB_PKCS1PADDING: 'RSA/ECB/PKCS1PADDING',
  378. /** @constant */
  379. RSA_ECB_OAEP_WITH_SHA256_AND_MGF1PADDING:
  380. 'RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING',
  381. /** @constant */
  382. FORGE_RSA_OAEP: 'RSA-OAEP',
  383. /** @constant */
  384. FORGE_RSAES_PKCS1_V1_5: 'RSAES-PKCS1-V1_5',
  385. /** @constant */
  386. MINIMUM_PRIME_CERTAINTY_LEVEL: 80,
  387. /** @constant */
  388. SHORT_EXPONENT_BIT_LENGTH: 256,
  389. /** @constant */
  390. EXPONENTIATION_PROOF_AUXILIARY_DATA: 'ExponentiationProof',
  391. /** @constant */
  392. PLAINTEXT_PROOF_AUXILIARY_DATA: 'PlaintextProof',
  393. /** @constant */
  394. SIMPLE_PLAINTEXT_EQUALITY_PROOF_AUXILIARY_DATA:
  395. 'SimplePlaintextEqualityProof',
  396. /** @constant */
  397. PLAINTEXT_EQUALITY_PROOF_AUXILIARY_DATA: 'PlaintextEqualityProof',
  398. /** @constant */
  399. PLAINTEXT_EXPONENT_EQUALITY_PROOF_AUXILIARY_DATA:
  400. 'PlaintextExponentEqualityProof'
  401. };
  402. var args = Array.prototype.slice.call(arguments);
  403. var callback = args.pop();
  404. var modules = (args[0] && typeof args[0] === 'string') ? args : args[0];
  405. return new Cryptolib(modules, callback);
  406. }
  407. cryptolib.modules = {};