History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/crypto/provider/CipherBlockChaining.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/crypto/provider/CipherBlockChaining.java+212−0
@@ -0,0 +1,212 @@
1+/*
2+ * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.crypto.provider;
27+
28+import java.security.InvalidKeyException;
29+
30+/**
31+ * This class represents ciphers in cipher block chaining (CBC) mode.
32+ *
33+ * <p>This mode is implemented independently of a particular cipher.
34+ * Ciphers to which this mode should apply (e.g., DES) must be
35+ * <i>plugged-in</i> using the constructor.
36+ *
37+ * <p>NOTE: This class does not deal with buffering or padding.
38+ *
39+ * @author Gigi Ankeny
40+ */
41+
42+class CipherBlockChaining extends FeedbackCipher {
43+
44+ /*
45+ * random bytes that are initialized with iv
46+ */
47+ protected byte[] r;
48+
49+ /*
50+ * output buffer
51+ */
52+ private byte[] k;
53+
54+ // variables for save/restore calls
55+ private byte[] rSave = null;
56+
57+ CipherBlockChaining(SymmetricCipher embeddedCipher) {
58+ super(embeddedCipher);
59+ k = new byte[blockSize];
60+ r = new byte[blockSize];
61+ }
62+
63+ /**
64+ * Gets the name of this feedback mode.
65+ *
66+ * @return the string <code>CBC</code>
67+ */
68+ String getFeedback() {
69+ return "CBC";
70+ }
71+
72+ /**
73+ * Initializes the cipher in the specified mode with the given key
74+ * and iv.
75+ *
76+ * @param decrypting flag indicating encryption or decryption
77+ * @param algorithm the algorithm name
78+ * @param key the key
79+ * @param iv the iv
80+ *
81+ * @exception InvalidKeyException if the given key is inappropriate for
82+ * initializing this cipher
83+ */
84+ void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
85+ throws InvalidKeyException {
86+ if ((key == null) || (iv == null) || (iv.length != blockSize)) {
87+ throw new InvalidKeyException("Internal error");
88+ }
89+ this.iv = iv;
90+ reset();
91+ embeddedCipher.init(decrypting, algorithm, key);
92+ }
93+
94+ /**
95+ * Resets the iv to its original value.
96+ * This is used when doFinal is called in the Cipher class, so that the
97+ * cipher can be reused (with its original iv).
98+ */
99+ void reset() {
100+ System.arraycopy(iv, 0, r, 0, blockSize);
101+ }
102+
103+ /**
104+ * Save the current content of this cipher.
105+ */
106+ void save() {
107+ if (rSave == null) {
108+ rSave = new byte[blockSize];
109+ }
110+ System.arraycopy(r, 0, rSave, 0, blockSize);
111+ }
112+
113+ /**
114+ * Restores the content of this cipher to the previous saved one.
115+ */
116+ void restore() {
117+ System.arraycopy(rSave, 0, r, 0, blockSize);
118+ }
119+
120+ /**
121+ * Performs encryption operation.
122+ *
123+ * <p>The input plain text <code>plain</code>, starting at
124+ * <code>plainOffset</code> and ending at
125+ * <code>(plainOffset + len - 1)</code>, is encrypted.
126+ * The result is stored in <code>cipher</code>, starting at
127+ * <code>cipherOffset</code>.
128+ *
129+ * <p>It is the application's responsibility to make sure that
130+ * <code>plainLen</code> is a multiple of the embedded cipher's block size,
131+ * as any excess bytes are ignored.
132+ *
133+ * @param plain the buffer with the input data to be encrypted
134+ * @param plainOffset the offset in <code>plain</code>
135+ * @param plainLen the length of the input data
136+ * @param cipher the buffer for the result
137+ * @param cipherOffset the offset in <code>cipher</code>
138+ */
139+ void encrypt(byte[] plain, int plainOffset, int plainLen,
140+ byte[] cipher, int cipherOffset)
141+ {
142+ int i;
143+ int endIndex = plainOffset + plainLen;
144+
145+ for (; plainOffset < endIndex;
146+ plainOffset+=blockSize, cipherOffset += blockSize) {
147+ for (i=0; i<blockSize; i++) {
148+ k[i] = (byte)(plain[i+plainOffset] ^ r[i]);
149+ }
150+ embeddedCipher.encryptBlock(k, 0, cipher, cipherOffset);
151+ System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
152+ }
153+ }
154+
155+ /**
156+ * Performs decryption operation.
157+ *
158+ * <p>The input cipher text <code>cipher</code>, starting at
159+ * <code>cipherOffset</code> and ending at
160+ * <code>(cipherOffset + len - 1)</code>, is decrypted.
161+ * The result is stored in <code>plain</code>, starting at
162+ * <code>plainOffset</code>.
163+ *
164+ * <p>It is the application's responsibility to make sure that
165+ * <code>cipherLen</code> is a multiple of the embedded cipher's block
166+ * size, as any excess bytes are ignored.
167+ *
168+ * <p>It is also the application's responsibility to make sure that
169+ * <code>init</code> has been called before this method is called.
170+ * (This check is omitted here, to avoid double checking.)
171+ *
172+ * @param cipher the buffer with the input data to be decrypted
173+ * @param cipherOffset the offset in <code>cipherOffset</code>
174+ * @param cipherLen the length of the input data
175+ * @param plain the buffer for the result
176+ * @param plainOffset the offset in <code>plain</code>
177+ *
178+ * @exception IllegalBlockSizeException if input data whose length does
179+ * not correspond to the embedded cipher's block size is passed to the
180+ * embedded cipher
181+ */
182+ void decrypt(byte[] cipher, int cipherOffset, int cipherLen,
183+ byte[] plain, int plainOffset)
184+ {
185+ int i;
186+ byte[] cipherOrig=null;
187+ int endIndex = cipherOffset + cipherLen;
188+
189+ if (cipher==plain && (cipherOffset >= plainOffset)
190+ && ((cipherOffset - plainOffset) < blockSize)) {
191+ // Save the original ciphertext blocks, so they can be
192+ // stored in the feedback register "r".
193+ // This is necessary because in this constellation, a
194+ // ciphertext block (or parts of it) will be overridden by
195+ // the plaintext result.
196+ cipherOrig = (byte[])cipher.clone();
197+ }
198+
199+ for (; cipherOffset < endIndex;
200+ cipherOffset += blockSize, plainOffset += blockSize) {
201+ embeddedCipher.decryptBlock(cipher, cipherOffset, k, 0);
202+ for (i = 0; i < blockSize; i++) {
203+ plain[i+plainOffset] = (byte)(k[i] ^ r[i]);
204+ }
205+ if (cipherOrig==null) {
206+ System.arraycopy(cipher, cipherOffset, r, 0, blockSize);
207+ } else {
208+ System.arraycopy(cipherOrig, cipherOffset, r, 0, blockSize);
209+ }
210+ }
211+ }
212+}