Re: CFB mode problems

Garrison M. Venn (gvenn@vail.net)
Mon, 08 Mar 1999 16:38:52 -0700

Date: Mon, 08 Mar 1999 16:38:52 -0700
From: "Garrison M. Venn" <gvenn@vail.net>
To: Jan Luehe <Jan.Luehe@eng.sun.com>
Subject: Re: CFB mode problems

This is a multi-part message in MIME format.
--------------34726C422BBC465224927470
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Jan Luehe wrote:

> Garrison:
>
> > I'm having problems with CFB modes (CFB64 and CFB8) both with DES and
> > Blowfish. As I could be doing something wrong, I do not know if this is
> > a bug. However OFB modes (both 8 and 64 bit) work fine. I'm treating
> > both modes symantically the same and do not know if the problems I'm
> > having are due to an incorrect symantic treatment of the CFB mode. Sorry
> > for the bandwidth but I do not know if this is a known problem. The bug
> > list did not report it. Any comments before I do a bug submital?
>
> Could you explain what your particular problem is?
>
> Thanks,
>
> Jan

Thanks for your response.

Basically I have reduced my problem in test code where I can replace the
static finals representing the mode and algorithm parameters. With the
algoritm set to Blowfish or DES, all OFB modes that I have tested (OFB8,
OFB64) produce correct results on "decryption." CFB modes do not (CFB8,
CFB32, CFB64). I'm assuming that I'm doing something wrong but I have no
clue. Interestingly the CFB modes 32 and 64 correctly "decrypt" the
first 32
or 64 bits respectively. There after only garbage is produced. I have
not
test CFB8 for this pattern. The code is attached. Please remember to
replace
the package for your environment.

Thanks in advance

Garrison Venn
gvenn@vail.net
--------------34726C422BBC465224927470
Content-Type: text/plain; charset=us-ascii; name="StreamCipherTest.java"
Content-Disposition: inline; filename="StreamCipherTest.java"
Content-Transfer-Encoding: 7bit

/*
* StreamCipherTest.java
*
* $Author$
*
* $Date$ $Revision$
*
* Copyright (c) 1998 Qui Vive, Inc. All Rights Reserved.
*
* Developed by Qui Vive
*/

package gtest.jdk12.jce;

import java.io.*;
import sun.misc.*;
import javax.crypto.*;
import java.security.*;
import javax.crypto.spec.*;
import java.lang.reflect.*;

/**
* Description
* <p>
*
* <strong>A Code Example</strong>
* <pre>
* StreamCipherTest t = new StreamCipherTest()
* </pre>
*
* @see java.xxx.yyy
*
* @author Garrison M. Venn / Qui Vive, Breckenridge Colorado
*/

public class StreamCipherTest
{
public StreamCipherTest (String fileName) throws Exception
{
_ourFile = new File(fileName);

_ourFile.createNewFile();

System.out.println("About to generate random object");
_ourRanGen = new SecureRandom();
System.out.println("Generated random object");

_ourCipher = Cipher.getInstance(ALG + '/' + MODE + '/' + PADDING);

KeyGenerator keyGen = KeyGenerator.getInstance(ALG);
keyGen.init(_ourRanGen);

_ourMasterKey = keyGen.generateKey();

_ourIV = new byte[IV_LENGTH];
}

public void writeIt () throws Exception
{
ByteArrayOutputStream array = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(array);

out.writeInt(10);
out.writeInt(20);
out.writeUTF("Hello There");

out.flush();
out.close();

byte decrypt[] = array.toByteArray();

_ourRanGen.nextBytes(_ourIV);
_ourCipher.init(Cipher.ENCRYPT_MODE,
_ourMasterKey,
new IvParameterSpec(_ourIV));

byte toWrite[] = _ourCipher.doFinal(decrypt,
0,
decrypt.length);

DataOutputStream fOut =
new DataOutputStream(new FileOutputStream(_ourFile));

fOut.write(_ourIV);
fOut.writeInt(toWrite.length);
fOut.write(toWrite);
fOut.flush();
fOut.close();
}

public void readIt () throws Exception
{
DataInputStream fIn =
new DataInputStream(new FileInputStream(_ourFile));

fIn.readFully(_ourIV);

int size = fIn.readInt();

byte encrypt[] = new byte[size];

fIn.readFully(encrypt);

fIn.close();

_ourCipher.init(Cipher.ENCRYPT_MODE,
_ourMasterKey,
new IvParameterSpec(_ourIV));

byte toRead[] = _ourCipher.doFinal(encrypt, 0, encrypt.length);

DataInputStream in =
new DataInputStream(new ByteArrayInputStream(toRead));

System.out.println("int value = " + in.readInt());
System.out.println("int value = " + in.readInt());
System.out.println("String value = " + in.readUTF());

in.close();
}

public static void main (String argv[]) throws Exception
{
Provider sunJce = new com.sun.crypto.provider.SunJCE();
Security.addProvider(sunJce);

if (argv.length == 1)
{
String filename = argv[0];

StreamCipherTest test = new StreamCipherTest(filename);

test.writeIt();
test.readIt();
}
else
{
System.err.println("java StreamCipherTest <filename>.");
}
}

private static final int IV_LENGTH = 8;
//private static final String MODE = "CFB64";
//private static final String MODE = "CFB32";
//private static final String MODE = "CFB8";
//private static final String MODE = "OFB64";
private static final String MODE = "OFB8";
//private static final int MASTER_KEY_LEN = 448;
private static final int MASTER_KEY_LEN = 56;
//private static final String ALG = "Blowfish";
private static final String ALG = "DES";
private static final String PADDING = "NoPadding";

private File _ourFile;
private SecretKey _ourMasterKey;
private byte _ourIV[];
private Cipher _ourCipher;
private SecureRandom _ourRanGen;

private static final String rcsid = "$Id$";
}

/*
* REVISION HISTORY
* ----------------
*
* $Log$
*
*/

--------------34726C422BBC465224927470--