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/CipherTextStealing.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/crypto/provider/CipherTextStealing.java+215−0
@@ -0,0 +1,215 @@
1/*
2 * Copyright (c) 2004, 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
26package com.sun.crypto.provider;
27
28import javax.crypto.IllegalBlockSizeException;
29import javax.crypto.ShortBufferException;
30
31/**
32 * This class represents ciphers in cipher text stealing (CTS) mode.
33 * <br>CTS provides a way to allow block ciphers to operate on partial
34 * blocks without padding, and all bits of the message go through
35 * the encryption algorithm, rather than simply being XOR'd.
36 * <br>More details can be found in RFC 2040 section 8 "Description
37 * of RC5-CTS".
38 *
39 * <p>This mode is implemented independently of a particular cipher.
40 * Ciphers to which this mode should apply (e.g., DES) must be
41 * <i>plugged-in</i> using the constructor.
42 *
43 * <p>NOTE#1: CTS requires the input data to be at least one block
44 * long. Thus, callers of this class has to buffer the input data
45 * to make sure the input data passed to encryptFinal()/decryptFinal()
46 * is not shorter than a block.
47 * <p>NOTE#2: This class does not deal with buffering or padding
48 * just like all other cipher mode implementations.
49 *
50 * @author Valerie Peng
51 */
52
53final class CipherTextStealing extends CipherBlockChaining {
54
55 CipherTextStealing(SymmetricCipher embeddedCipher) {
56 super(embeddedCipher);
57 }
58
59 /**
60 * Gets the name of this feedback mode.
61 *
62 * @return the string <code>CBC</code>
63 */
64 String getFeedback() {
65 return "CTS";
66 }
67
68 /**
69 * Performs the last encryption operation.
70 *
71 * <p>The input plain text <code>plain</code>, starting at
72 * <code>plainOffset</code> and ending at
73 * <code>(plainOffset + len - 1)</code>, is encrypted.
74 * The result is stored in <code>cipher</code>, starting at
75 * <code>cipherOffset</code>.
76 *
77 * <p>It is the application's responsibility to make sure that
78 * <code>plainLen</code> is a multiple of the embedded cipher's block size,
79 * as any excess bytes are ignored.
80 *
81 * @param plain the buffer with the input data to be encrypted
82 * @param plainOffset the offset in <code>plain</code>
83 * @param plainLen the length of the input data
84 * @param cipher the buffer for the result
85 * @param cipherOffset the offset in <code>cipher</code>
86 */
87 void encryptFinal(byte[] plain, int plainOffset, int plainLen,
88 byte[] cipher, int cipherOffset)
89 throws IllegalBlockSizeException {
90
91 if (plainLen < blockSize) {
92 throw new IllegalBlockSizeException("input is too short!");
93 } else if (plainLen == blockSize) {
94 encrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
95 } else {
96 // number of bytes in the last block
97 int nLeft = plainLen % blockSize;
98 if (nLeft == 0) {
99 encrypt(plain, plainOffset, plainLen, cipher, cipherOffset);
100 // swap the last two blocks after encryption
101 int lastBlkIndex = cipherOffset + plainLen - blockSize;
102 int nextToLastBlkIndex = lastBlkIndex - blockSize;
103 byte[] tmp = new byte[blockSize];
104 System.arraycopy(cipher, lastBlkIndex, tmp, 0, blockSize);
105 System.arraycopy(cipher, nextToLastBlkIndex,
106 cipher, lastBlkIndex, blockSize);
107 System.arraycopy(tmp, 0, cipher, nextToLastBlkIndex,
108 blockSize);
109 } else {
110 int newPlainLen = plainLen - (blockSize + nLeft);
111 if (newPlainLen > 0) {
112 encrypt(plain, plainOffset, newPlainLen, cipher,
113 cipherOffset);
114 plainOffset += newPlainLen;
115 cipherOffset += newPlainLen;
116 }
117
118 // Do final CTS step for last two blocks (the second of which
119 // may or may not be incomplete).
120 byte[] tmp = new byte[blockSize];
121 // now encrypt the next-to-last block
122 for (int i = 0; i < blockSize; i++) {
123 tmp[i] = (byte) (plain[plainOffset+i] ^ r[i]);
124 }
125 byte[] tmp2 = new byte[blockSize];
126 embeddedCipher.encryptBlock(tmp, 0, tmp2, 0);
127 System.arraycopy(tmp2, 0, cipher,
128 cipherOffset+blockSize, nLeft);
129 // encrypt the last block
130 for (int i=0; i<nLeft; i++) {
131 tmp2[i] = (byte)
132 (plain[plainOffset+blockSize+i] ^ tmp2[i]);
133 }
134 embeddedCipher.encryptBlock(tmp2, 0, cipher, cipherOffset);
135 }
136 }
137 }
138
139 /**
140 * Performs decryption operation.
141 *
142 * <p>The input cipher text <code>cipher</code>, starting at
143 * <code>cipherOffset</code> and ending at
144 * <code>(cipherOffset + len - 1)</code>, is decrypted.
145 * The result is stored in <code>plain</code>, starting at
146 * <code>plainOffset</code>.
147 *
148 * <p>It is the application's responsibility to make sure that
149 * <code>cipherLen</code> is a multiple of the embedded cipher's block
150 * size, as any excess bytes are ignored.
151 *
152 * <p>It is also the application's responsibility to make sure that
153 * <code>init</code> has been called before this method is called.
154 * (This check is omitted here, to avoid double checking.)
155 *
156 * @param cipher the buffer with the input data to be decrypted
157 * @param cipherOffset the offset in <code>cipherOffset</code>
158 * @param cipherLen the length of the input data
159 * @param plain the buffer for the result
160 * @param plainOffset the offset in <code>plain</code>
161 */
162 void decryptFinal(byte[] cipher, int cipherOffset, int cipherLen,
163 byte[] plain, int plainOffset)
164 throws IllegalBlockSizeException {
165 if (cipherLen < blockSize) {
166 throw new IllegalBlockSizeException("input is too short!");
167 } else if (cipherLen == blockSize) {
168 decrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
169 } else {
170 // number of bytes in the last block
171 int nLeft = cipherLen % blockSize;
172 if (nLeft == 0) {
173 // swap the last two blocks before decryption
174 int lastBlkIndex = cipherOffset + cipherLen - blockSize;
175 int nextToLastBlkIndex =
176 cipherOffset + cipherLen - 2*blockSize;
177 byte[] tmp = new byte[2*blockSize];
178 System.arraycopy(cipher, lastBlkIndex, tmp, 0, blockSize);
179 System.arraycopy(cipher, nextToLastBlkIndex,
180 tmp, blockSize, blockSize);
181 int cipherLen2 = cipherLen-2*blockSize;
182 decrypt(cipher, cipherOffset, cipherLen2, plain, plainOffset);
183 decrypt(tmp, 0, 2*blockSize, plain, plainOffset+cipherLen2);
184 } else {
185 int newCipherLen = cipherLen-(blockSize+nLeft);
186 if (newCipherLen > 0) {
187 decrypt(cipher, cipherOffset, newCipherLen, plain,
188 plainOffset);
189 cipherOffset += newCipherLen;
190 plainOffset += newCipherLen;
191 }
192 // Do final CTS step for last two blocks (the second of which
193 // may or may not be incomplete).
194
195 // now decrypt the next-to-last block
196 byte[] tmp = new byte[blockSize];
197 embeddedCipher.decryptBlock(cipher, cipherOffset, tmp, 0);
198 for (int i = 0; i < nLeft; i++) {
199 plain[plainOffset+blockSize+i] =
200 (byte) (cipher[cipherOffset+blockSize+i] ^ tmp[i]);
201 }
202
203 // decrypt the last block
204 System.arraycopy(cipher, cipherOffset+blockSize, tmp, 0,
205 nLeft);
206 embeddedCipher.decryptBlock(tmp, 0, plain, plainOffset);
207 //System.arraycopy(r, 0, tmp, 0, r.length);
208 for (int i=0; i<blockSize; i++) {
209 plain[plainOffset+i] = (byte)
210 (plain[plainOffset+i]^r[i]);
211 }
212 }
213 }
214 }
215}