Skip to content

Commit 5e4a844

Browse files
authored
Merge pull request #166 from cconlon/gcmCipherFix
Fixes for Cipher, AlgorithmParameters, SecretKeyFactory
2 parents 08889ab + 671b428 commit 5e4a844

15 files changed

+1276
-55
lines changed

README_JCE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,20 @@ The JCE provider currently supports the following algorithms:
103103

104104
Cipher Class
105105
AES/CBC/NoPadding
106+
Aliases: AES_128/CBC/NoPadding, AES_192/CBC/NoPadding, AES_256/CBC/NoPadding
107+
OIDs: 2.16.840.1.101.3.4.1.2, 2.16.840.1.101.3.4.1.22, 2.16.840.1.101.3.4.1.42
106108
AES/CBC/PKCS5Padding
107109
AES/CTS/NoPadding
108110
AES/CCM/NoPadding
109111
AES/CTR/NoPadding
110112
AES/ECB/NoPadding
113+
Aliases: AES_128/ECB/NoPadding, AES_192/ECB/NoPadding, AES_256/ECB/NoPadding
114+
OIDs: 2.16.840.1.101.3.4.1.1, 2.16.840.1.101.3.4.1.21, 2.16.840.1.101.3.4.1.41
111115
AES/ECB/PKCS5Padding (aliased also as: AES)
112116
AES/GCM/NoPadding
113117
AES/OFB/NoPadding
118+
Aliases: AES_128/OFB/NoPadding, AES_192/OFB/NoPadding, AES_256/OFB/NoPadding
119+
OIDs: 2.16.840.1.101.3.4.1.3, 2.16.840.1.101.3.4.1.23, 2.16.840.1.101.3.4.1.43
114120
DESede/CBC/NoPadding
115121
RSA
116122
RSA/ECB/PKCS1Padding
@@ -120,10 +126,15 @@ The JCE provider currently supports the following algorithms:
120126
AESGMAC (aliased also as: AES-GMAC)
121127
HmacMD5
122128
HmacSHA1
129+
OID: 1.2.840.113549.2.7
123130
HmacSHA224
131+
OID: 1.2.840.113549.2.8
124132
HmacSHA256
133+
OID: 1.2.840.113549.2.9
125134
HmacSHA384
135+
OID: 1.2.840.113549.2.10
126136
HmacSHA512
137+
OID: 1.2.840.113549.2.11
127138
HmacSHA3-224
128139
HmacSHA3-256
129140
HmacSHA3-384

src/main/java/com/wolfssl/provider/jce/WolfCryptAesParameters.java

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import java.security.spec.InvalidParameterSpecException;
2828
import javax.crypto.spec.IvParameterSpec;
2929

30+
import com.wolfssl.wolfcrypt.Aes;
31+
3032
/**
3133
* wolfCrypt JCE AlgorithmParametersSpi implementation for AES parameters
3234
*/
@@ -46,6 +48,12 @@ public WolfCryptAesParameters() {
4648
protected void engineInit(AlgorithmParameterSpec paramSpec)
4749
throws InvalidParameterSpecException {
4850

51+
/* Prevent double initialization */
52+
if (this.ivSpec != null) {
53+
throw new InvalidParameterSpecException(
54+
"AlgorithmParameters already initialized");
55+
}
56+
4957
if (!(paramSpec instanceof IvParameterSpec)) {
5058
throw new InvalidParameterSpecException(
5159
"Only IvParameterSpec supported");
@@ -60,7 +68,7 @@ protected void engineInit(AlgorithmParameterSpec paramSpec)
6068
}
6169

6270
/* AES block size is 16 bytes, IV should match */
63-
if (spec.getIV().length != 16) {
71+
if (spec.getIV().length != Aes.BLOCK_SIZE) {
6472
throw new InvalidParameterSpecException(
6573
"AES IV must be 16 bytes, got: " + spec.getIV().length);
6674
}
@@ -73,14 +81,58 @@ protected void engineInit(AlgorithmParameterSpec paramSpec)
7381
protected void engineInit(byte[] params)
7482
throws IOException {
7583

76-
throw new IOException("Encoded AES parameters not supported");
84+
/* Prevent double initialization */
85+
if (this.ivSpec != null) {
86+
throw new IOException(
87+
"AlgorithmParameters already initialized");
88+
}
89+
90+
if (params == null) {
91+
throw new NullPointerException("params must not be null");
92+
}
93+
94+
if (params.length == 0) {
95+
throw new IOException("AES parameters cannot be empty");
96+
}
97+
98+
/* AES IV parameters are encoded as ASN.1 OCTET STRING:
99+
* tag (0x04) + length + IV bytes
100+
* Expected: 04 10 [16 IV bytes] = 18 bytes */
101+
if (params.length != Aes.BLOCK_SIZE + 2) {
102+
throw new IOException(
103+
"Invalid AES parameter encoding length: " + params.length);
104+
}
105+
106+
/* Verify OCTET STRING tag */
107+
if (params[0] != 0x04) {
108+
throw new IOException(
109+
"DER input not an octet string");
110+
}
111+
112+
/* Verify length is 16 (0x10) */
113+
if (params[1] != 0x10) {
114+
throw new IOException(
115+
"Invalid AES IV length in encoding: " + params[1]);
116+
}
117+
118+
/* Extract IV bytes (skip tag and length) */
119+
byte[] iv = new byte[Aes.BLOCK_SIZE];
120+
System.arraycopy(params, 2, iv, 0, Aes.BLOCK_SIZE);
121+
122+
this.ivSpec = new IvParameterSpec(iv);
77123
}
78124

79125
@Override
80126
protected void engineInit(byte[] params, String format)
81127
throws IOException {
82128

83-
throw new IOException("Encoded AES parameters not supported");
129+
if (format != null && !format.equalsIgnoreCase("ASN.1") &&
130+
!format.equalsIgnoreCase("DER")) {
131+
throw new IOException("Unsupported format: " + format +
132+
", only ASN.1 and DER supported");
133+
}
134+
135+
engineInit(params);
84136
}
85137

86138
@Override
@@ -110,12 +162,38 @@ protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(
110162

111163
@Override
112164
protected byte[] engineGetEncoded() throws IOException {
113-
throw new IOException("Encoded AES parameters not supported");
165+
166+
byte[] iv;
167+
byte[] encoded;
168+
169+
if (this.ivSpec == null) {
170+
throw new IOException("AES parameters not initialized");
171+
}
172+
173+
iv = this.ivSpec.getIV();
174+
if (iv == null || iv.length != Aes.BLOCK_SIZE) {
175+
throw new IOException("Invalid AES IV for encoding");
176+
}
177+
178+
/* Encode as OCTET STRING: tag (0x04) + len (0x10) + IV */
179+
encoded = new byte[18];
180+
encoded[0] = 0x04; /* OCTET STRING */
181+
encoded[1] = 0x10; /* length = 16 */
182+
System.arraycopy(iv, 0, encoded, 2, Aes.BLOCK_SIZE);
183+
184+
return encoded;
114185
}
115186

116187
@Override
117188
protected byte[] engineGetEncoded(String format) throws IOException {
118-
throw new IOException("Encoded AES parameters not supported");
189+
190+
if (format != null && !format.equalsIgnoreCase("ASN.1") &&
191+
!format.equalsIgnoreCase("DER")) {
192+
throw new IOException("Unsupported format: " + format +
193+
", only ASN.1 and DER supported");
194+
}
195+
196+
return engineGetEncoded();
119197
}
120198

121199
@Override

src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,9 @@ private void wolfCryptCipherInit(int opmode, Key key,
807807
AlgorithmParameterSpec spec, SecureRandom random)
808808
throws InvalidKeyException, InvalidAlgorithmParameterException {
809809

810+
/* Reset buffered data from any previous operation */
811+
buffered = new byte[0];
812+
810813
InitializeNativeStructs();
811814
wolfCryptSetDirection(opmode);
812815
wolfCryptSetIV(spec, random);

0 commit comments

Comments
 (0)