Permalink
Browse files

restore ecc, cbc

  • Loading branch information...
1 parent 5170137 commit 514276afc8cb8d0a19a4945cb846695371521dce Mike Hamburg committed May 23, 2011
Showing with 998 additions and 2 deletions.
  1. +3 −1 Makefile
  2. +3 −1 configure
  3. +115 −0 core/cbc.js
  4. +380 −0 core/ecc.js
  5. +33 −0 test/cbc_test.js
  6. +413 −0 test/cbc_vectors.js
  7. +18 −0 test/ecdh_test.js
  8. +29 −0 test/ecdsa_test.js
  9. +4 −0 test/run_tests_browser.js
View
@@ -60,12 +60,14 @@ TEST_SCRIPTS= $(TEST_COMMON) \
test/aes_vectors.js test/aes_test.js \
test/ocb2_vectors.js test/ocb2_test.js \
test/ccm_vectors.js test/ccm_test.js \
+ test/cbc_vectors.js test/cbc_test.js \
test/sha256_vectors.js test/sha256_test.js \
test/sha256_test_brute_force.js \
test/sha1_vectors.js test/sha1_test.js \
test/hmac_vectors.js test/hmac_test.js \
test/pbkdf2_test.js \
- test/bn_vectors.js test/bn_test.js
+ test/bn_vectors.js test/bn_test.js \
+ test/ecdsa_test.js test/ecdh_test.js
TEST_SCRIPTS_OPT= $(TEST_COMMON) \
test/srp_vectors.js test/srp_test.js
View
@@ -4,7 +4,7 @@ use strict;
my ($arg, $i, $j, $targ);
-my @targets = qw/sjcl aes bitArray codecString codecHex codecBase64 codecBytes bn sha256 sha1 ccm ocb2 hmac pbkdf2 srp random convenience/;
+my @targets = qw/sjcl aes bitArray codecString codecHex codecBase64 codecBytes bn sha256 sha1 ccm cbc ecc ocb2 hmac pbkdf2 srp random convenience/;
my %deps = ('aes'=>'sjcl',
'bitArray'=>'sjcl',
'codecString'=>'bitArray',
@@ -19,6 +19,8 @@ my %deps = ('aes'=>'sjcl',
'pbkdf2'=>'hmac',
'srp'=>'sha1,bn,bitArray',
'bn'=>'bitArray,random',
+ 'ecc'=>'bn',
+ 'cbc'=>'bitArray,aes',
'random'=>'sha256,aes',
'convenience'=>'ccm,pbkdf2,random');
View
@@ -0,0 +1,115 @@
+/** @fileOverview CBC mode implementation
+ *
+ * @author Emily Stark
+ * @author Mike Hamburg
+ * @author Dan Boneh
+ */
+
+/** @namespace
+ * Dangerous: CBC mode with PKCS#5 padding.
+ *
+ * @author Emily Stark
+ * @author Mike Hamburg
+ * @author Dan Boneh
+ */
+if (sjcl.beware === undefined) {
+ sjcl.beware = {};
+}
+sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."
+] = function() {
+ sjcl.mode.cbc = {
+ /** The name of the mode.
+ * @constant
+ */
+ name: "cbc",
+
+ /** Encrypt in CBC mode with PKCS#5 padding.
+ * @param {Object} prp The block cipher. It must have a block size of 16 bytes.
+ * @param {bitArray} plaintext The plaintext data.
+ * @param {bitArray} iv The initialization value.
+ * @param {bitArray} [adata=[]] The authenticated data. Must be empty.
+ * @return The encrypted data, an array of bytes.
+ * @throws {sjcl.exception.invalid} if the IV isn't exactly 128 bits, or if any adata is specified.
+ */
+ encrypt: function(prp, plaintext, iv, adata) {
+ if (adata && adata.length) {
+ throw new sjcl.exception.invalid("cbc can't authenticate data");
+ }
+ if (sjcl.bitArray.bitLength(iv) !== 128) {
+ throw new sjcl.exception.invalid("cbc iv must be 128 bits");
+ }
+ var i,
+ w = sjcl.bitArray,
+ xor = w._xor4,
+ bl = w.bitLength(plaintext),
+ bp = 0,
+ output = [];
+
+ if (bl&7) {
+ throw new sjcl.exception.invalid("pkcs#5 padding only works for multiples of a byte");
+ }
+
+ for (i=0; bp+128 <= bl; i+=4, bp+=128) {
+ /* Encrypt a non-final block */
+ iv = prp.encrypt(xor(iv, plaintext.slice(i,i+4)));
+ output.splice(i,0,iv[0],iv[1],iv[2],iv[3]);
+ }
+
+ /* Construct the pad. */
+ bl = (16 - ((bl >> 3) & 15)) * 0x1010101;
+
+ /* Pad and encrypt. */
+ iv = prp.encrypt(xor(iv,w.concat(plaintext,[bl,bl,bl,bl]).slice(i,i+4)));
+ output.splice(i,0,iv[0],iv[1],iv[2],iv[3]);
+ return output;
+ },
+
+ /** Decrypt in CBC mode.
+ * @param {Object} prp The block cipher. It must have a block size of 16 bytes.
+ * @param {bitArray} ciphertext The ciphertext data.
+ * @param {bitArray} iv The initialization value.
+ * @param {bitArray} [adata=[]] The authenticated data. It must be empty.
+ * @return The decrypted data, an array of bytes.
+ * @throws {sjcl.exception.invalid} if the IV isn't exactly 128 bits, or if any adata is specified.
+ * @throws {sjcl.exception.corrupt} if if the message is corrupt.
+ */
+ decrypt: function(prp, ciphertext, iv, adata) {
+ if (adata && adata.length) {
+ throw new sjcl.exception.invalid("cbc can't authenticate data");
+ }
+ if (sjcl.bitArray.bitLength(iv) !== 128) {
+ throw new sjcl.exception.invalid("cbc iv must be 128 bits");
+ }
+ if ((sjcl.bitArray.bitLength(ciphertext) & 127) || !ciphertext.length) {
+ throw new sjcl.exception.corrupt("cbc ciphertext must be a positive multiple of the block size");
+ }
+ var i,
+ w = sjcl.bitArray,
+ xor = w._xor4,
+ bi, bo,
+ output = [];
+
+ adata = adata || [];
+
+ for (i=0; i<ciphertext.length; i+=4) {
+ bi = ciphertext.slice(i,i+4);
+ bo = xor(iv,prp.decrypt(bi));
+ output.splice(i,0,bo[0],bo[1],bo[2],bo[3]);
+ iv = bi;
+ }
+
+ /* check and remove the pad */
+ bi = output[i-1] & 255;
+ if (bi == 0 || bi > 16) {
+ throw new sjcl.exception.corrupt("pkcs#5 padding corrupt");
+ }
+ bo = bi * 0x1010101;
+ if (!w.equal(w.bitSlice([bo,bo,bo,bo], 0, bi*8),
+ w.bitSlice(output, output.length*32 - bi*8, output.length*32))) {
+ throw new sjcl.exception.corrupt("pkcs#5 padding corrupt");
+ }
+
+ return w.bitSlice(output, 0, output.length*32 - bi*8);
+ }
+ };
+};
Oops, something went wrong.

0 comments on commit 514276a

Please sign in to comment.