123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- // Copyright 2012 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Implementation of CBC mode for block ciphers. See
- * http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
- * #Cipher-block_chaining_.28CBC.29. for description.
- *
- * @author nnaze@google.com (Nathan Naze)
- */
- goog.provide('goog.crypt.Cbc');
- goog.require('goog.array');
- goog.require('goog.asserts');
- goog.require('goog.crypt');
- goog.require('goog.crypt.BlockCipher');
- /**
- * Implements the CBC mode for block ciphers. See
- * http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation
- * #Cipher-block_chaining_.28CBC.29
- *
- * @param {!goog.crypt.BlockCipher} cipher The block cipher to use.
- * @constructor
- * @final
- * @struct
- */
- goog.crypt.Cbc = function(cipher) {
- /**
- * Block cipher.
- * @type {!goog.crypt.BlockCipher}
- * @private
- */
- this.cipher_ = cipher;
- };
- /**
- * Encrypt a message.
- *
- * @param {!Array<number>|!Uint8Array} plainText Message to encrypt. An array of
- * bytes. The length should be a multiple of the block size.
- * @param {!Array<number>|!Uint8Array} initialVector Initial vector for the CBC
- * mode. An array of bytes with the same length as the block size.
- * @return {!Array<number>} Encrypted message.
- */
- goog.crypt.Cbc.prototype.encrypt = function(plainText, initialVector) {
- goog.asserts.assert(
- plainText.length % this.cipher_.BLOCK_SIZE == 0,
- 'Data\'s length must be multiple of block size.');
- goog.asserts.assert(
- initialVector.length == this.cipher_.BLOCK_SIZE,
- 'Initial vector must be size of one block.');
- // Implementation of
- // http://en.wikipedia.org/wiki/File:Cbc_encryption.png
- var cipherText = [];
- var vector = initialVector;
- // Generate each block of the encrypted cypher text.
- for (var blockStartIndex = 0; blockStartIndex < plainText.length;
- blockStartIndex += this.cipher_.BLOCK_SIZE) {
- // Takes one block from the input message.
- var plainTextBlock = goog.array.slice(
- plainText, blockStartIndex, blockStartIndex + this.cipher_.BLOCK_SIZE);
- var input = goog.crypt.xorByteArray(plainTextBlock, vector);
- var resultBlock = this.cipher_.encrypt(input);
- goog.array.extend(cipherText, resultBlock);
- vector = resultBlock;
- }
- return cipherText;
- };
- /**
- * Decrypt a message.
- *
- * @param {!Array<number>|!Uint8Array} cipherText Message to decrypt. An array
- * of bytes. The length should be a multiple of the block size.
- * @param {!Array<number>|!Uint8Array} initialVector Initial vector for the CBC
- * mode. An array of bytes with the same length as the block size.
- * @return {!Array<number>} Decrypted message.
- */
- goog.crypt.Cbc.prototype.decrypt = function(cipherText, initialVector) {
- goog.asserts.assert(
- cipherText.length % this.cipher_.BLOCK_SIZE == 0,
- 'Data\'s length must be multiple of block size.');
- goog.asserts.assert(
- initialVector.length == this.cipher_.BLOCK_SIZE,
- 'Initial vector must be size of one block.');
- // Implementation of
- // http://en.wikipedia.org/wiki/File:Cbc_decryption.png
- var plainText = [];
- var blockStartIndex = 0;
- var vector = initialVector;
- // Generate each block of the decrypted plain text.
- while (blockStartIndex < cipherText.length) {
- // Takes one block.
- var cipherTextBlock = goog.array.slice(
- cipherText, blockStartIndex, blockStartIndex + this.cipher_.BLOCK_SIZE);
- var resultBlock = this.cipher_.decrypt(cipherTextBlock);
- var plainTextBlock = goog.crypt.xorByteArray(vector, resultBlock);
- goog.array.extend(plainText, plainTextBlock);
- vector = cipherTextBlock;
- blockStartIndex += this.cipher_.BLOCK_SIZE;
- }
- return plainText;
- };
|