Path: blob/trunk/third_party/closure/goog/crypt/cbc.js
2868 views
// Copyright 2012 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Implementation of CBC mode for block ciphers. See16* http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation17* #Cipher-block_chaining_.28CBC.29. for description.18*19* @author [email protected] (Nathan Naze)20*/2122goog.provide('goog.crypt.Cbc');2324goog.require('goog.array');25goog.require('goog.asserts');26goog.require('goog.crypt');27goog.require('goog.crypt.BlockCipher');28293031/**32* Implements the CBC mode for block ciphers. See33* http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation34* #Cipher-block_chaining_.28CBC.2935*36* @param {!goog.crypt.BlockCipher} cipher The block cipher to use.37* @constructor38* @final39* @struct40*/41goog.crypt.Cbc = function(cipher) {4243/**44* Block cipher.45* @type {!goog.crypt.BlockCipher}46* @private47*/48this.cipher_ = cipher;49};505152/**53* Encrypt a message.54*55* @param {!Array<number>|!Uint8Array} plainText Message to encrypt. An array of56* bytes. The length should be a multiple of the block size.57* @param {!Array<number>|!Uint8Array} initialVector Initial vector for the CBC58* mode. An array of bytes with the same length as the block size.59* @return {!Array<number>} Encrypted message.60*/61goog.crypt.Cbc.prototype.encrypt = function(plainText, initialVector) {6263goog.asserts.assert(64plainText.length % this.cipher_.BLOCK_SIZE == 0,65'Data\'s length must be multiple of block size.');6667goog.asserts.assert(68initialVector.length == this.cipher_.BLOCK_SIZE,69'Initial vector must be size of one block.');7071// Implementation of72// http://en.wikipedia.org/wiki/File:Cbc_encryption.png7374var cipherText = [];75var vector = initialVector;7677// Generate each block of the encrypted cypher text.78for (var blockStartIndex = 0; blockStartIndex < plainText.length;79blockStartIndex += this.cipher_.BLOCK_SIZE) {80// Takes one block from the input message.81var plainTextBlock = goog.array.slice(82plainText, blockStartIndex, blockStartIndex + this.cipher_.BLOCK_SIZE);8384var input = goog.crypt.xorByteArray(plainTextBlock, vector);85var resultBlock = this.cipher_.encrypt(input);8687goog.array.extend(cipherText, resultBlock);88vector = resultBlock;89}9091return cipherText;92};939495/**96* Decrypt a message.97*98* @param {!Array<number>|!Uint8Array} cipherText Message to decrypt. An array99* of bytes. The length should be a multiple of the block size.100* @param {!Array<number>|!Uint8Array} initialVector Initial vector for the CBC101* mode. An array of bytes with the same length as the block size.102* @return {!Array<number>} Decrypted message.103*/104goog.crypt.Cbc.prototype.decrypt = function(cipherText, initialVector) {105106goog.asserts.assert(107cipherText.length % this.cipher_.BLOCK_SIZE == 0,108'Data\'s length must be multiple of block size.');109110goog.asserts.assert(111initialVector.length == this.cipher_.BLOCK_SIZE,112'Initial vector must be size of one block.');113114// Implementation of115// http://en.wikipedia.org/wiki/File:Cbc_decryption.png116117var plainText = [];118var blockStartIndex = 0;119var vector = initialVector;120121// Generate each block of the decrypted plain text.122while (blockStartIndex < cipherText.length) {123// Takes one block.124var cipherTextBlock = goog.array.slice(125cipherText, blockStartIndex, blockStartIndex + this.cipher_.BLOCK_SIZE);126127var resultBlock = this.cipher_.decrypt(cipherTextBlock);128var plainTextBlock = goog.crypt.xorByteArray(vector, resultBlock);129130goog.array.extend(plainText, plainTextBlock);131vector = cipherTextBlock;132133blockStartIndex += this.cipher_.BLOCK_SIZE;134}135136return plainText;137};138139140