001: /*
002: * @(#)Cipher.java 1.11 02/07/24 @(#)
003: *
004: * Copyright (c) 2000-2001 Sun Microsystems, Inc. All rights reserved.
005: * PROPRIETARY/CONFIDENTIAL
006: * Use is subject to license terms.
007: */
008:
009: package com.sun.portal.kssl;
010:
011: import com.sun.portal.ksecurity.Key;
012: import com.sun.portal.ksecurity.SecretKey;
013: import com.sun.portal.ksecurity.KeyBuilder;
014: import com.sun.portal.ksecurity.CryptoException;
015:
016: public class BlockCipher extends Cipher {
017:
018: protected byte mode;
019: protected boolean isBuffered = false;
020: protected int BLOCK_SIZE;
021: protected byte[] prevBlock;
022: protected byte[] buf;
023: protected int bufCount;
024:
025: protected byte[] scratchBuf = new byte[BLOCK_SIZE];
026:
027: /** Protected constructor. */
028: protected BlockCipher() {
029: }
030:
031: public byte getAlgorithm() {
032: return Cipher.ALG_UNKNOWN;
033: }
034:
035: public void init(Key theKey, byte theMode) throws CryptoException {
036: throw new CryptoException(CryptoException.ILLEGAL_USE);
037: }
038:
039: public void init(Key theKey, byte theMode, byte[] b, int off,
040: int len) throws CryptoException {
041: prevBlock = new byte[BLOCK_SIZE];
042: buf = new byte[BLOCK_SIZE];
043: scratchBuf = new byte[BLOCK_SIZE];
044:
045: if (theMode == Cipher.MODE_DECRYPT) {
046: System.arraycopy(b, 0, prevBlock, 0, BLOCK_SIZE);
047: bufCount = 0;
048: } else {
049: // set IV
050: System.arraycopy(b, 0, buf, 0, BLOCK_SIZE);
051: bufCount = 0;
052: }
053:
054: init(theKey, theMode);
055:
056: }
057:
058: public int update(byte[] in, int inOffset, int inLen, byte[] out,
059: int outOffset) {
060:
061: byte[] t;
062: if (mode == Cipher.MODE_DECRYPT) {
063: if (in == null && !isBuffered)
064: return 0;
065: int i = 0;
066: if (isBuffered) {
067: i = ModeCBC(scratchBuf, 0, BLOCK_SIZE, out, outOffset);
068:
069: if (in != null)
070: i += ModeCBC(in, inOffset, inLen, out, outOffset
071: + BLOCK_SIZE);
072: } else {
073: i = ModeCBC(in, inOffset, inLen, out, outOffset);
074: }
075: isBuffered = false;
076: return i;
077: }
078: return ModeCBC(in, inOffset, inLen, out, outOffset);
079: }
080:
081: public int doFinal(byte[] inBuf, int inOff, int inLen,
082: byte[] outBuf, int outOff) throws CryptoException {
083: return update(inBuf, inOff, inLen, outBuf, outOff);
084: }
085:
086: protected int ModeCBC(byte[] in, int inOffset, int inLen,
087: byte[] out, int outOffset) {
088: if (mode == Cipher.MODE_DECRYPT) {
089: int ret = 0;
090: int remainder;
091: while (inLen >= (remainder = BLOCK_SIZE - bufCount)) {
092:
093: for (int i = 0; i < remainder; i++)
094: buf[bufCount++] = in[inOffset++];
095:
096: // encrypt to output
097: coreCrypt(buf, 0, out, outOffset);
098:
099: // xor in previous block
100: for (int i = 0; i < BLOCK_SIZE; i++)
101: out[outOffset++] ^= prevBlock[i];
102:
103: // store cipher text as IV for next block
104: for (int i = 0; i < BLOCK_SIZE; i++)
105: prevBlock[i] = buf[i];
106:
107: inLen -= BLOCK_SIZE;
108: ret += BLOCK_SIZE;
109: bufCount = 0;
110: }
111:
112: for (int i = 0; i < inLen; i++)
113: buf[bufCount++] = in[inOffset++];
114:
115: return ret;
116:
117: } else {
118: int ret = 0;
119: int remainder;
120: while (inLen >= (remainder = BLOCK_SIZE - bufCount)) {
121: for (int i = 0; i < remainder; i++)
122: buf[bufCount++] ^= in[inOffset++];
123:
124: coreCrypt(buf, 0, buf, 0);
125: System.arraycopy(buf, 0, out, outOffset, BLOCK_SIZE);
126: inLen -= remainder;
127: outOffset += BLOCK_SIZE;
128: ret += BLOCK_SIZE;
129: bufCount = 0;
130: }
131:
132: for (int i = 0; i < inLen; i++)
133: buf[bufCount++] ^= in[inOffset++];
134:
135: return ret;
136: }
137: }
138:
139: protected void coreCrypt(byte[] in, int inOffset, byte[] out,
140: int outOffset) {
141: return;
142: }
143:
144: }
|