Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
da6c04b0
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
da6c04b0
编写于
7月 25, 2015
作者:
A
asmotrak
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8048596: Tests for AEAD ciphers
Reviewed-by: valeriep
上级
b9d354e3
变更
8
展开全部
隐藏空白更改
内联
并排
Showing
8 changed file
with
2115 addition
and
0 deletion
+2115
-0
test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
+753
-0
test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java
...sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java
+218
-0
test/com/sun/crypto/provider/Cipher/AEAD/Helper.java
test/com/sun/crypto/provider/Cipher/AEAD/Helper.java
+33
-0
test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
+87
-0
test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
+317
-0
test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
+423
-0
test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java
...com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java
+110
-0
test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
+174
-0
未找到文件。
test/com/sun/crypto/provider/Cipher/AEAD/Encrypt.java
0 → 100644
浏览文件 @
da6c04b0
此差异已折叠。
点击以展开。
test/com/sun/crypto/provider/Cipher/AEAD/GCMParameterSpecTest.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.security.NoSuchAlgorithmException
;
import
java.security.NoSuchProviderException
;
import
java.util.Arrays
;
import
javax.crypto.SecretKey
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.spec.GCMParameterSpec
;
/*
* @test
* @bug 8048596
* @summary Check if GCMParameterSpec works as expected
*/
public
class
GCMParameterSpecTest
{
private
static
final
int
[]
IV_LENGTHS
=
{
96
,
8
,
1024
};
private
static
final
int
[]
KEY_LENGTHS
=
{
128
,
192
,
256
};
private
static
final
int
[]
DATA_LENGTHS
=
{
0
,
128
,
1024
};
private
static
final
int
[]
AAD_LENGTHS
=
{
0
,
128
,
1024
};
private
static
final
int
[]
TAG_LENGTHS
=
{
128
,
120
,
112
,
104
,
96
};
private
static
final
int
[]
OFFSETS
=
{
0
,
2
,
5
,
99
};
private
static
final
String
TRANSFORMATION
=
"AES/GCM/NoPadding"
;
private
static
final
String
TEMPLATE
=
"Test:\n tag = %d\n"
+
" IV length = %d\n data length = %d\n"
+
" AAD length = %d\n offset = %d\n keylength = %d\n"
;
private
final
byte
[]
IV
;
private
final
byte
[]
IVO
;
private
final
byte
[]
data
;
private
final
byte
[]
AAD
;
private
final
SecretKey
key
;
private
final
int
tagLength
;
private
final
int
IVlength
;
private
final
int
offset
;
/**
* Initialize IV, IV with offset, plain text, AAD and SecretKey
*
* @param keyLength length of a secret key
* @param tagLength tag length
* @param IVlength IV length
* @param offset offset in a buffer for IV
* @param textLength plain text length
* @param AADLength AAD length
*/
public
GCMParameterSpecTest
(
int
keyLength
,
int
tagLength
,
int
IVlength
,
int
offset
,
int
textLength
,
int
AADLength
)
throws
NoSuchAlgorithmException
,
NoSuchProviderException
{
this
.
tagLength
=
tagLength
;
// save tag length
this
.
IVlength
=
IVlength
;
// save IV length
this
.
offset
=
offset
;
// save IV offset
// prepare IV
IV
=
Helper
.
generateBytes
(
IVlength
);
// prepare IV with offset
IVO
=
new
byte
[
this
.
IVlength
+
this
.
offset
];
System
.
arraycopy
(
IV
,
0
,
IVO
,
offset
,
this
.
IVlength
);
// prepare data
data
=
Helper
.
generateBytes
(
textLength
);
// prepare AAD
AAD
=
Helper
.
generateBytes
(
AADLength
);
// init a secret key
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
"AES"
,
"SunJCE"
);
kg
.
init
(
keyLength
);
key
=
kg
.
generateKey
();
}
/*
* Run the test for each key length, tag length, IV length, plain text
* length, AAD length and offset.
*/
public
static
void
main
(
String
[]
args
)
throws
Exception
{
boolean
success
=
true
;
for
(
int
k
:
KEY_LENGTHS
)
{
if
(
k
>
Cipher
.
getMaxAllowedKeyLength
(
TRANSFORMATION
))
{
// skip this if this key length is larger than what's
// allowed in the jce jurisdiction policy files
continue
;
}
for
(
int
t
:
TAG_LENGTHS
)
{
for
(
int
n
:
IV_LENGTHS
)
{
for
(
int
p
:
DATA_LENGTHS
)
{
for
(
int
a
:
AAD_LENGTHS
)
{
for
(
int
o
:
OFFSETS
)
{
System
.
out
.
printf
(
TEMPLATE
,
t
,
n
,
p
,
a
,
o
,
k
);
success
&=
new
GCMParameterSpecTest
(
k
,
t
,
n
,
o
,
p
,
a
).
doTest
();
}
}
}
}
}
}
if
(!
success
)
{
throw
new
RuntimeException
(
"At least one test case failed"
);
}
}
/*
* Run the test:
* - check if result of encryption of plain text is the same
* when parameters constructed with different GCMParameterSpec
* constructors are used
* - check if GCMParameterSpec.getTLen() is equal to actual tag length
* - check if ciphertext has the same length as plaintext
*/
private
boolean
doTest
()
throws
Exception
{
GCMParameterSpec
spec1
=
new
GCMParameterSpec
(
tagLength
,
IV
);
GCMParameterSpec
spec2
=
new
GCMParameterSpec
(
tagLength
,
IVO
,
offset
,
IVlength
);
byte
[]
cipherText1
=
getCipherTextBySpec
(
spec1
);
if
(
cipherText1
==
null
)
{
return
false
;
}
byte
[]
cipherText2
=
getCipherTextBySpec
(
spec2
);
if
(
cipherText2
==
null
)
{
return
false
;
}
if
(!
Arrays
.
equals
(
cipherText1
,
cipherText2
))
{
System
.
out
.
println
(
"Cipher texts are different"
);
return
false
;
}
if
(
spec1
.
getTLen
()
!=
spec2
.
getTLen
())
{
System
.
out
.
println
(
"Tag lengths are not equal"
);
return
false
;
}
byte
[]
recoveredText1
=
recoverCipherText
(
cipherText1
,
spec2
);
if
(
recoveredText1
==
null
)
{
return
false
;
}
byte
[]
recoveredText2
=
recoverCipherText
(
cipherText2
,
spec1
);
if
(
recoveredText2
==
null
)
{
return
false
;
}
if
(!
Arrays
.
equals
(
recoveredText1
,
recoveredText2
))
{
System
.
out
.
println
(
"Recovered texts are different"
);
return
false
;
}
if
(!
Arrays
.
equals
(
recoveredText1
,
data
))
{
System
.
out
.
println
(
"Recovered and original texts are not equal"
);
return
false
;
}
return
true
;
}
/*
* Encrypt a plain text, and check if GCMParameterSpec.getIV()
* is equal to Cipher.getIV()
*/
private
byte
[]
getCipherTextBySpec
(
GCMParameterSpec
spec
)
throws
Exception
{
// init a cipher
Cipher
cipher
=
createCipher
(
Cipher
.
ENCRYPT_MODE
,
spec
);
cipher
.
updateAAD
(
AAD
);
byte
[]
cipherText
=
cipher
.
doFinal
(
data
);
// check IVs
if
(!
Arrays
.
equals
(
cipher
.
getIV
(),
spec
.
getIV
()))
{
System
.
out
.
println
(
"IV in parameters is incorrect"
);
return
null
;
}
if
(
spec
.
getTLen
()
!=
(
cipherText
.
length
-
data
.
length
)
*
8
)
{
System
.
out
.
println
(
"Tag length is incorrect"
);
return
null
;
}
return
cipherText
;
}
private
byte
[]
recoverCipherText
(
byte
[]
cipherText
,
GCMParameterSpec
spec
)
throws
Exception
{
// init a cipher
Cipher
cipher
=
createCipher
(
Cipher
.
DECRYPT_MODE
,
spec
);
// check IVs
if
(!
Arrays
.
equals
(
cipher
.
getIV
(),
spec
.
getIV
()))
{
System
.
out
.
println
(
"IV in parameters is incorrect"
);
return
null
;
}
cipher
.
updateAAD
(
AAD
);
return
cipher
.
doFinal
(
cipherText
);
}
private
Cipher
createCipher
(
int
mode
,
GCMParameterSpec
spec
)
throws
Exception
{
Cipher
cipher
=
Cipher
.
getInstance
(
TRANSFORMATION
,
"SunJCE"
);
cipher
.
init
(
mode
,
key
,
spec
);
return
cipher
;
}
}
test/com/sun/crypto/provider/Cipher/AEAD/Helper.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public
class
Helper
{
public
static
byte
[]
generateBytes
(
int
length
)
{
byte
[]
bytes
=
new
byte
[
length
];
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
bytes
[
i
]
=
(
byte
)
(
i
%
256
);
}
return
bytes
;
}
}
test/com/sun/crypto/provider/Cipher/AEAD/KeyWrapper.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.security.AlgorithmParameters
;
import
java.security.Key
;
import
java.util.Arrays
;
import
javax.crypto.SecretKey
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
/*
* @test
* @bug 8048596
* @summary Check if a key wrapper works properly with GCM mode
*/
public
class
KeyWrapper
{
static
final
String
AES
=
"AES"
;
static
final
String
TRANSFORMATION
=
"AES/GCM/NoPadding"
;
static
final
String
PROVIDER
=
"SunJCE"
;
static
final
int
KEY_LENGTH
=
128
;
public
static
void
main
(
String
argv
[])
throws
Exception
{
doTest
(
PROVIDER
,
TRANSFORMATION
);
}
private
static
void
doTest
(
String
provider
,
String
algo
)
throws
Exception
{
SecretKey
key
;
SecretKey
keyToWrap
;
// init a secret Key
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
AES
,
PROVIDER
);
kg
.
init
(
KEY_LENGTH
);
key
=
kg
.
generateKey
();
keyToWrap
=
kg
.
generateKey
();
// initialization
Cipher
cipher
=
Cipher
.
getInstance
(
algo
,
provider
);
cipher
.
init
(
Cipher
.
WRAP_MODE
,
key
);
AlgorithmParameters
params
=
cipher
.
getParameters
();
// wrap the key
byte
[]
keyWrapper
=
cipher
.
wrap
(
keyToWrap
);
try
{
// check if we can't wrap it again with the same key/IV
keyWrapper
=
cipher
.
wrap
(
keyToWrap
);
throw
new
RuntimeException
(
"FAILED: expected IllegalStateException hasn't "
+
"been thrown "
);
}
catch
(
IllegalStateException
ise
)
{
System
.
out
.
println
(
ise
.
getMessage
());
System
.
out
.
println
(
"Expected exception"
);
}
// unwrap the key
cipher
.
init
(
Cipher
.
UNWRAP_MODE
,
key
,
params
);
cipher
.
unwrap
(
keyWrapper
,
algo
,
Cipher
.
SECRET_KEY
);
// check if we can unwrap second time
Key
unwrapKey
=
cipher
.
unwrap
(
keyWrapper
,
algo
,
Cipher
.
SECRET_KEY
);
if
(!
Arrays
.
equals
(
keyToWrap
.
getEncoded
(),
unwrapKey
.
getEncoded
()))
{
throw
new
RuntimeException
(
"FAILED: original and unwrapped keys are not equal"
);
}
}
}
test/com/sun/crypto/provider/Cipher/AEAD/ReadWriteSkip.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.security.GeneralSecurityException
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Arrays
;
import
javax.crypto.Cipher
;
import
javax.crypto.CipherInputStream
;
import
javax.crypto.CipherOutputStream
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.SecretKey
;
/*
* @test
* @bug 8048596
* @summary Test CICO AEAD read/write/skip operations
*/
public
class
ReadWriteSkip
{
static
enum
BufferType
{
BYTE_ARRAY_BUFFERING
,
INT_BYTE_BUFFERING
}
static
final
int
KEY_LENGTHS
[]
=
{
128
,
192
,
256
};
static
final
int
TXT_LENGTHS
[]
=
{
800
,
0
};
static
final
int
AAD_LENGTHS
[]
=
{
0
,
100
};
static
final
int
BLOCK
=
50
;
static
final
int
SAVE
=
45
;
static
final
int
DISCARD
=
BLOCK
-
SAVE
;
static
final
String
PROVIDER
=
"SunJCE"
;
static
final
String
AES
=
"AES"
;
static
final
String
GCM
=
"GCM"
;
static
final
String
PADDING
=
"NoPadding"
;
static
final
String
TRANSFORM
=
AES
+
"/"
+
GCM
+
"/"
+
PADDING
;
final
SecretKey
key
;
final
byte
[]
plaintext
;
final
byte
[]
AAD
;
final
int
textLength
;;
final
int
keyLength
;
Cipher
encryptCipher
;
Cipher
decryptCipher
;
CipherInputStream
ciInput
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
boolean
success
=
true
;
for
(
int
keyLength
:
KEY_LENGTHS
)
{
if
(
keyLength
>
Cipher
.
getMaxAllowedKeyLength
(
TRANSFORM
))
{
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
continue
;
}
for
(
int
textLength
:
TXT_LENGTHS
)
{
for
(
int
AADLength
:
AAD_LENGTHS
)
{
System
.
out
.
println
(
"Key length = "
+
keyLength
+
", text length = "
+
textLength
+
", AAD length = "
+
AADLength
);
try
{
run
(
keyLength
,
textLength
,
AADLength
);
System
.
out
.
println
(
"Test case passed"
);
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Test case failed: "
+
e
);
success
=
false
;
}
}
}
}
if
(!
success
)
{
throw
new
RuntimeException
(
"At least one test case failed"
);
}
System
.
out
.
println
(
"Test passed"
);
}
ReadWriteSkip
(
int
keyLength
,
int
textLength
,
int
AADLength
)
throws
Exception
{
this
.
keyLength
=
keyLength
;
this
.
textLength
=
textLength
;
// init AAD
this
.
AAD
=
Helper
.
generateBytes
(
AADLength
);
// init a secret Key
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
AES
,
PROVIDER
);
kg
.
init
(
this
.
keyLength
);
this
.
key
=
kg
.
generateKey
();
this
.
plaintext
=
Helper
.
generateBytes
(
textLength
);
}
final
void
doTest
(
BufferType
type
)
throws
Exception
{
// init ciphers
encryptCipher
=
createCipher
(
Cipher
.
ENCRYPT_MODE
);
decryptCipher
=
createCipher
(
Cipher
.
DECRYPT_MODE
);
// init cipher input stream
ciInput
=
new
CipherInputStream
(
new
ByteArrayInputStream
(
plaintext
),
encryptCipher
);
runTest
(
type
);
}
void
runTest
(
BufferType
type
)
throws
Exception
{}
private
Cipher
createCipher
(
int
mode
)
throws
GeneralSecurityException
{
Cipher
cipher
=
Cipher
.
getInstance
(
TRANSFORM
,
PROVIDER
);
if
(
mode
==
Cipher
.
ENCRYPT_MODE
)
{
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
}
else
{
if
(
encryptCipher
!=
null
)
{
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key
,
encryptCipher
.
getParameters
());
}
else
{
throw
new
RuntimeException
(
"Can't create a cipher"
);
}
}
cipher
.
updateAAD
(
AAD
);
return
cipher
;
}
/*
* Run test cases
*/
static
void
run
(
int
keyLength
,
int
textLength
,
int
AADLength
)
throws
Exception
{
new
ReadWriteTest
(
keyLength
,
textLength
,
AADLength
)
.
doTest
(
BufferType
.
BYTE_ARRAY_BUFFERING
);
new
ReadWriteTest
(
keyLength
,
textLength
,
AADLength
)
.
doTest
(
BufferType
.
INT_BYTE_BUFFERING
);
new
SkipTest
(
keyLength
,
textLength
,
AADLength
)
.
doTest
(
BufferType
.
BYTE_ARRAY_BUFFERING
);
new
SkipTest
(
keyLength
,
textLength
,
AADLength
)
.
doTest
(
BufferType
.
INT_BYTE_BUFFERING
);
}
static
void
check
(
byte
[]
first
,
byte
[]
second
)
{
if
(!
Arrays
.
equals
(
first
,
second
))
{
throw
new
RuntimeException
(
"Arrays are not equal"
);
}
}
/*
* CICO AEAD read/write functional test.
*
* Check if encrypt/decrypt operations work correctly.
*
* Test scenario:
* - initializes plain text
* - for given AEAD algorithm instantiates encrypt and decrypt Ciphers
* - instantiates CipherInputStream with the encrypt Cipher
* - instantiates CipherOutputStream with the decrypt Cipher
* - performs reading from the CipherInputStream (encryption data)
* and writing to the CipherOutputStream (decryption). As a result,
* output of the CipherOutputStream should be equal
* with original plain text
* - check if the original plain text is equal to output
* of the CipherOutputStream
* - if it is equal the test passes, otherwise it fails
*/
static
class
ReadWriteTest
extends
ReadWriteSkip
{
public
ReadWriteTest
(
int
keyLength
,
int
textLength
,
int
AADLength
)
throws
Exception
{
super
(
keyLength
,
textLength
,
AADLength
);
}
@Override
public
void
runTest
(
BufferType
bufType
)
throws
IOException
,
GeneralSecurityException
{
ByteArrayOutputStream
baOutput
=
new
ByteArrayOutputStream
();
try
(
CipherOutputStream
ciOutput
=
new
CipherOutputStream
(
baOutput
,
decryptCipher
))
{
if
(
bufType
==
BufferType
.
BYTE_ARRAY_BUFFERING
)
{
doByteTest
(
ciOutput
);
}
else
{
doIntTest
(
ciOutput
);
}
}
check
(
plaintext
,
baOutput
.
toByteArray
());
}
/*
* Implements byte array buffering type test case
*/
public
void
doByteTest
(
CipherOutputStream
out
)
throws
IOException
{
byte
[]
buffer
=
Helper
.
generateBytes
(
textLength
+
1
);
int
len
=
ciInput
.
read
(
buffer
);
while
(
len
!=
-
1
)
{
out
.
write
(
buffer
,
0
,
len
);
len
=
ciInput
.
read
(
buffer
);
}
}
/*
* Implements integer buffering type test case
*/
public
void
doIntTest
(
CipherOutputStream
out
)
throws
IOException
{
int
buffer
=
ciInput
.
read
();
while
(
buffer
!=
-
1
)
{
out
.
write
(
buffer
);
buffer
=
ciInput
.
read
();
}
}
}
/*
* CICO AEAD SKIP functional test.
*
* Checks if the encrypt/decrypt operations work correctly
* when skip() method is used.
*
* Test scenario:
* - initializes a plain text
* - initializes ciphers
* - initializes cipher streams
* - split plain text to TEXT_SIZE/BLOCK blocks
* - read from CipherInputStream2 one block at time
* - the last DISCARD = BLOCK - SAVE bytes are skipping for each block
* - therefore, plain text data go through CipherInputStream1 (encrypting)
* and CipherInputStream2 (decrypting)
* - as a result, output should equal to the original text
* except DISCART byte for each block
* - check result buffers
*/
static
class
SkipTest
extends
ReadWriteSkip
{
private
final
int
numberOfBlocks
;
private
final
byte
[]
outputText
;
public
SkipTest
(
int
keyLength
,
int
textLength
,
int
AADLength
)
throws
Exception
{
super
(
keyLength
,
textLength
,
AADLength
);
numberOfBlocks
=
this
.
textLength
/
BLOCK
;
outputText
=
new
byte
[
numberOfBlocks
*
SAVE
];
}
private
void
doByteTest
(
int
blockNum
,
CipherInputStream
cis
)
throws
IOException
{
int
index
=
blockNum
*
SAVE
;
int
len
=
cis
.
read
(
outputText
,
index
,
SAVE
);
index
+=
len
;
int
read
=
0
;
while
(
len
!=
SAVE
&&
read
!=
-
1
)
{
read
=
cis
.
read
(
outputText
,
index
,
SAVE
-
len
);
len
+=
read
;
index
+=
read
;
}
}
private
void
doIntTest
(
int
blockNum
,
CipherInputStream
cis
)
throws
IOException
{
int
i
=
blockNum
*
SAVE
;
for
(
int
j
=
0
;
j
<
SAVE
&&
i
<
outputText
.
length
;
j
++,
i
++)
{
int
b
=
cis
.
read
();
if
(
b
!=
-
1
)
{
outputText
[
i
]
=
(
byte
)
b
;
}
}
}
@Override
public
void
runTest
(
BufferType
type
)
throws
IOException
,
NoSuchAlgorithmException
{
try
(
CipherInputStream
cis
=
new
CipherInputStream
(
ciInput
,
decryptCipher
))
{
for
(
int
i
=
0
;
i
<
numberOfBlocks
;
i
++)
{
if
(
type
==
BufferType
.
BYTE_ARRAY_BUFFERING
)
{
doByteTest
(
i
,
cis
);
}
else
{
doIntTest
(
i
,
cis
);
}
if
(
cis
.
available
()
>=
DISCARD
)
{
cis
.
skip
(
DISCARD
);
}
else
{
for
(
int
k
=
0
;
k
<
DISCARD
;
k
++)
{
cis
.
read
();
}
}
}
}
byte
[]
expectedText
=
new
byte
[
numberOfBlocks
*
SAVE
];
for
(
int
m
=
0
;
m
<
numberOfBlocks
;
m
++)
{
for
(
int
n
=
0
;
n
<
SAVE
;
n
++)
{
expectedText
[
m
*
SAVE
+
n
]
=
plaintext
[
m
*
BLOCK
+
n
];
}
}
check
(
expectedText
,
outputText
);
}
}
}
test/com/sun/crypto/provider/Cipher/AEAD/SameBuffer.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.nio.ByteBuffer
;
import
java.security.AlgorithmParameters
;
import
java.security.Provider
;
import
java.security.Security
;
import
javax.crypto.SecretKey
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.spec.GCMParameterSpec
;
/*
* @test
* @bug 8048596
* @summary Check if AEAD operations work correctly when buffers used
* for storing plain text and cipher text are overlapped or the same
*/
public
class
SameBuffer
{
private
static
final
String
PROVIDER
=
"SunJCE"
;
private
static
final
String
AES
=
"AES"
;
private
static
final
String
GCM
=
"GCM"
;
private
static
final
String
PADDING
=
"NoPadding"
;
private
static
final
int
OFFSET
=
2
;
private
static
final
int
OFFSETS
=
4
;
private
static
final
int
KEY_LENGTHS
[]
=
{
128
,
192
,
256
};
private
static
final
int
TEXT_LENGTHS
[]
=
{
0
,
1024
};
private
static
final
int
AAD_LENGTHS
[]
=
{
0
,
1024
};
private
final
Provider
provider
;
private
final
SecretKey
key
;
private
final
String
transformation
;
private
final
int
textLength
;
private
final
int
AADLength
;
/**
* Constructor of the test
*
* @param provider security provider
* @param keyStrength key length
* @param textLength length of data
* @param AADLength AAD length
*/
public
SameBuffer
(
Provider
provider
,
String
algorithm
,
String
mode
,
String
padding
,
int
keyStrength
,
int
textLength
,
int
AADLength
)
throws
Exception
{
// init a secret key
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
algorithm
,
provider
);
kg
.
init
(
keyStrength
);
key
=
kg
.
generateKey
();
this
.
transformation
=
algorithm
+
"/"
+
mode
+
"/"
+
padding
;
this
.
provider
=
provider
;
this
.
textLength
=
textLength
;
this
.
AADLength
=
AADLength
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
Provider
p
=
Security
.
getProvider
(
PROVIDER
);
for
(
int
keyLength
:
KEY_LENGTHS
)
{
for
(
int
textLength
:
TEXT_LENGTHS
)
{
for
(
int
AADLength
:
AAD_LENGTHS
)
{
for
(
int
i
=
0
;
i
<
OFFSETS
;
i
++)
{
// try different offsets
int
offset
=
i
*
OFFSET
;
runTest
(
p
,
AES
,
GCM
,
PADDING
,
keyLength
,
textLength
,
AADLength
,
offset
);
}
}
}
}
}
/*
* Run single test case with given parameters
*/
static
void
runTest
(
Provider
p
,
String
algo
,
String
mode
,
String
padding
,
int
keyLength
,
int
textLength
,
int
AADLength
,
int
offset
)
throws
Exception
{
System
.
out
.
println
(
"Testing "
+
keyLength
+
" key length; "
+
textLength
+
" text lenght; "
+
AADLength
+
" AAD length; "
+
offset
+
" offset"
);
if
(
keyLength
>
Cipher
.
getMaxAllowedKeyLength
(
algo
))
{
// skip this if this key length is larger than what's
// configured in the jce jurisdiction policy files
return
;
}
SameBuffer
test
=
new
SameBuffer
(
p
,
algo
,
mode
,
padding
,
keyLength
,
textLength
,
AADLength
);
/*
* There are four test cases:
* 1. AAD and text are placed in separated byte arrays
* 2. AAD and text are placed in the same byte array
* 3. AAD and text are placed in separated byte buffers
* 4. AAD and text are placed in the same byte buffer
*/
Cipher
ci
=
test
.
createCipher
(
Cipher
.
ENCRYPT_MODE
,
null
);
AlgorithmParameters
params
=
ci
.
getParameters
();
test
.
doTestWithSeparateArrays
(
offset
,
params
);
test
.
doTestWithSameArrays
(
offset
,
params
);
test
.
doTestWithSeparatedBuffer
(
offset
,
params
);
test
.
doTestWithSameBuffer
(
offset
,
params
);
}
/*
* Run the test in case when AAD and text are placed in separated byte
* arrays.
*/
private
void
doTestWithSeparateArrays
(
int
offset
,
AlgorithmParameters
params
)
throws
Exception
{
// prepare buffers to test
Cipher
c
=
createCipher
(
Cipher
.
ENCRYPT_MODE
,
params
);
int
outputLength
=
c
.
getOutputSize
(
textLength
);
int
outputBufSize
=
outputLength
+
offset
*
2
;
byte
[]
inputText
=
Helper
.
generateBytes
(
outputBufSize
);
byte
[]
AAD
=
Helper
.
generateBytes
(
AADLength
);
// do the test
runGCMWithSeparateArray
(
Cipher
.
ENCRYPT_MODE
,
AAD
,
inputText
,
offset
*
2
,
textLength
,
offset
,
params
);
int
tagLength
=
c
.
getParameters
()
.
getParameterSpec
(
GCMParameterSpec
.
class
).
getTLen
()
/
8
;
runGCMWithSeparateArray
(
Cipher
.
DECRYPT_MODE
,
AAD
,
inputText
,
offset
,
textLength
+
tagLength
,
offset
,
params
);
}
/**
* Run the test in case when AAD and text are placed in the same byte
* array.
*/
private
void
doTestWithSameArrays
(
int
offset
,
AlgorithmParameters
params
)
throws
Exception
{
// prepare buffers to test
Cipher
c
=
createCipher
(
Cipher
.
ENCRYPT_MODE
,
params
);
int
outputLength
=
c
.
getOutputSize
(
textLength
);
int
outputBufSize
=
AADLength
+
outputLength
+
offset
*
2
;
byte
[]
AAD_and_text
=
Helper
.
generateBytes
(
outputBufSize
);
// do the test
runGCMWithSameArray
(
Cipher
.
ENCRYPT_MODE
,
AAD_and_text
,
AADLength
+
offset
,
textLength
,
params
);
int
tagLength
=
c
.
getParameters
()
.
getParameterSpec
(
GCMParameterSpec
.
class
).
getTLen
()
/
8
;
runGCMWithSameArray
(
Cipher
.
DECRYPT_MODE
,
AAD_and_text
,
AADLength
+
offset
,
textLength
+
tagLength
,
params
);
}
/*
* Run the test in case when AAD and text are placed in separated ByteBuffer
*/
private
void
doTestWithSeparatedBuffer
(
int
offset
,
AlgorithmParameters
params
)
throws
Exception
{
// prepare AAD byte buffers to test
byte
[]
AAD
=
Helper
.
generateBytes
(
AADLength
);
ByteBuffer
AAD_Buf
=
ByteBuffer
.
allocate
(
AADLength
);
AAD_Buf
.
put
(
AAD
,
0
,
AAD
.
length
);
AAD_Buf
.
flip
();
// prepare text byte buffer to encrypt/decrypt
Cipher
c
=
createCipher
(
Cipher
.
ENCRYPT_MODE
,
params
);
int
outputLength
=
c
.
getOutputSize
(
textLength
);
int
outputBufSize
=
outputLength
+
offset
;
byte
[]
inputText
=
Helper
.
generateBytes
(
outputBufSize
);
ByteBuffer
plainTextBB
=
ByteBuffer
.
allocateDirect
(
inputText
.
length
);
plainTextBB
.
put
(
inputText
);
plainTextBB
.
position
(
offset
);
plainTextBB
.
limit
(
offset
+
textLength
);
// do test
runGCMWithSeparateBuffers
(
Cipher
.
ENCRYPT_MODE
,
AAD_Buf
,
plainTextBB
,
offset
,
textLength
,
params
);
int
tagLength
=
c
.
getParameters
()
.
getParameterSpec
(
GCMParameterSpec
.
class
).
getTLen
()
/
8
;
plainTextBB
.
position
(
offset
);
plainTextBB
.
limit
(
offset
+
textLength
+
tagLength
);
runGCMWithSeparateBuffers
(
Cipher
.
DECRYPT_MODE
,
AAD_Buf
,
plainTextBB
,
offset
,
textLength
+
tagLength
,
params
);
}
/*
* Run the test in case when AAD and text are placed in the same ByteBuffer
*/
private
void
doTestWithSameBuffer
(
int
offset
,
AlgorithmParameters
params
)
throws
Exception
{
// calculate output length
Cipher
c
=
createCipher
(
Cipher
.
ENCRYPT_MODE
,
params
);
int
outputLength
=
c
.
getOutputSize
(
textLength
);
// prepare byte buffer contained AAD and plain text
int
bufSize
=
AADLength
+
offset
+
outputLength
;
byte
[]
AAD_and_Text
=
Helper
.
generateBytes
(
bufSize
);
ByteBuffer
AAD_and_Text_Buf
=
ByteBuffer
.
allocate
(
bufSize
);
AAD_and_Text_Buf
.
put
(
AAD_and_Text
,
0
,
AAD_and_Text
.
length
);
// do test
runGCMWithSameBuffer
(
Cipher
.
ENCRYPT_MODE
,
AAD_and_Text_Buf
,
offset
,
textLength
,
params
);
int
tagLength
=
c
.
getParameters
()
.
getParameterSpec
(
GCMParameterSpec
.
class
).
getTLen
()
/
8
;
AAD_and_Text_Buf
.
limit
(
AADLength
+
offset
+
textLength
+
tagLength
);
runGCMWithSameBuffer
(
Cipher
.
DECRYPT_MODE
,
AAD_and_Text_Buf
,
offset
,
textLength
+
tagLength
,
params
);
}
/*
* Execute GCM encryption/decryption of a text placed in a byte array.
* AAD is placed in the separated byte array.
* Data are processed twice:
* - in a separately allocated buffer
* - in the text buffer
* Check if two results are equal
*/
private
void
runGCMWithSeparateArray
(
int
mode
,
byte
[]
AAD
,
byte
[]
text
,
int
txtOffset
,
int
lenght
,
int
offset
,
AlgorithmParameters
params
)
throws
Exception
{
// first, generate the cipher text at an allocated buffer
Cipher
cipher
=
createCipher
(
mode
,
params
);
cipher
.
updateAAD
(
AAD
);
byte
[]
outputText
=
cipher
.
doFinal
(
text
,
txtOffset
,
lenght
);
// new cipher for encrypt operation
Cipher
anotherCipher
=
createCipher
(
mode
,
params
);
anotherCipher
.
updateAAD
(
AAD
);
// next, generate cipher text again at the same buffer of plain text
int
myoff
=
offset
;
int
off
=
anotherCipher
.
update
(
text
,
txtOffset
,
lenght
,
text
,
myoff
);
anotherCipher
.
doFinal
(
text
,
myoff
+
off
);
// check if two resutls are equal
if
(!
isEqual
(
text
,
myoff
,
outputText
,
0
,
outputText
.
length
))
{
throw
new
RuntimeException
(
"Two results not equal, mode:"
+
mode
);
}
}
/*
* Execute GCM encrption/decryption of a text. The AAD and text to process
* are placed in the same byte array. Data are processed twice:
* - in a separetly allocated buffer
* - in a buffer that shares content of the AAD_and_Text_BA
* Check if two results are equal
*/
private
void
runGCMWithSameArray
(
int
mode
,
byte
[]
array
,
int
txtOffset
,
int
length
,
AlgorithmParameters
params
)
throws
Exception
{
// first, generate cipher text at an allocated buffer
Cipher
cipher
=
createCipher
(
mode
,
params
);
cipher
.
updateAAD
(
array
,
0
,
AADLength
);
byte
[]
outputText
=
cipher
.
doFinal
(
array
,
txtOffset
,
length
);
// new cipher for encrypt operation
Cipher
anotherCipher
=
createCipher
(
mode
,
params
);
anotherCipher
.
updateAAD
(
array
,
0
,
AADLength
);
// next, generate cipher text again at the same buffer of plain text
int
off
=
anotherCipher
.
update
(
array
,
txtOffset
,
length
,
array
,
txtOffset
);
anotherCipher
.
doFinal
(
array
,
txtOffset
+
off
);
// check if two results are equal or not
if
(!
isEqual
(
array
,
txtOffset
,
outputText
,
0
,
outputText
.
length
))
{
throw
new
RuntimeException
(
"Two results are not equal, mode:"
+
mode
);
}
}
/*
* Execute GCM encryption/decryption of textBB. AAD and text to process are
* placed in different byte buffers. Data are processed twice:
* - in a separately allocated buffer
* - in a buffer that shares content of the textBB
* Check if results are equal
*/
private
void
runGCMWithSeparateBuffers
(
int
mode
,
ByteBuffer
buffer
,
ByteBuffer
textBB
,
int
txtOffset
,
int
dataLength
,
AlgorithmParameters
params
)
throws
Exception
{
// take offset into account
textBB
.
position
(
txtOffset
);
textBB
.
mark
();
// first, generate the cipher text at an allocated buffer
Cipher
cipher
=
createCipher
(
mode
,
params
);
cipher
.
updateAAD
(
buffer
);
buffer
.
flip
();
ByteBuffer
outBB
=
ByteBuffer
.
allocateDirect
(
cipher
.
getOutputSize
(
dataLength
));
cipher
.
doFinal
(
textBB
,
outBB
);
// get cipher text in outBB
outBB
.
flip
();
// restore positions
textBB
.
reset
();
// next, generate cipher text again in a buffer that shares content
Cipher
anotherCipher
=
createCipher
(
mode
,
params
);
anotherCipher
.
updateAAD
(
buffer
);
buffer
.
flip
();
ByteBuffer
buf2
=
textBB
.
duplicate
();
// buf2 shares textBuf context
buf2
.
limit
(
txtOffset
+
anotherCipher
.
getOutputSize
(
dataLength
));
int
dataProcessed2
=
anotherCipher
.
doFinal
(
textBB
,
buf2
);
buf2
.
position
(
txtOffset
);
buf2
.
limit
(
txtOffset
+
dataProcessed2
);
if
(!
buf2
.
equals
(
outBB
))
{
throw
new
RuntimeException
(
"Two results are not equal, mode:"
+
mode
);
}
}
/*
* Execute GCM encryption/decryption of text. AAD and a text to process are
* placed in the same buffer. Data is processed twice:
* - in a separately allocated buffer
* - in a buffer that shares content of the AAD_and_Text_BB
*/
private
void
runGCMWithSameBuffer
(
int
mode
,
ByteBuffer
buffer
,
int
txtOffset
,
int
length
,
AlgorithmParameters
params
)
throws
Exception
{
// allocate a separate buffer
Cipher
cipher
=
createCipher
(
mode
,
params
);
ByteBuffer
outBB
=
ByteBuffer
.
allocateDirect
(
cipher
.
getOutputSize
(
length
));
// first, generate the cipher text at an allocated buffer
buffer
.
flip
();
buffer
.
limit
(
AADLength
);
cipher
.
updateAAD
(
buffer
);
buffer
.
limit
(
AADLength
+
txtOffset
+
length
);
buffer
.
position
(
AADLength
+
txtOffset
);
cipher
.
doFinal
(
buffer
,
outBB
);
outBB
.
flip
();
// cipher text in outBB
// next, generate cipherText again in the same buffer
Cipher
anotherCipher
=
createCipher
(
mode
,
params
);
buffer
.
flip
();
buffer
.
limit
(
AADLength
);
anotherCipher
.
updateAAD
(
buffer
);
buffer
.
limit
(
AADLength
+
txtOffset
+
length
);
buffer
.
position
(
AADLength
+
txtOffset
);
// share textBuf context
ByteBuffer
buf2
=
buffer
.
duplicate
();
buf2
.
limit
(
AADLength
+
txtOffset
+
anotherCipher
.
getOutputSize
(
length
));
int
dataProcessed2
=
anotherCipher
.
doFinal
(
buffer
,
buf2
);
buf2
.
position
(
AADLength
+
txtOffset
);
buf2
.
limit
(
AADLength
+
txtOffset
+
dataProcessed2
);
if
(!
buf2
.
equals
(
outBB
))
{
throw
new
RuntimeException
(
"Two results are not equal, mode:"
+
mode
);
}
}
private
boolean
isEqual
(
byte
[]
A
,
int
offsetA
,
byte
[]
B
,
int
offsetB
,
int
bytesToCompare
)
{
System
.
out
.
println
(
"offsetA: "
+
offsetA
+
" offsetB: "
+
offsetA
+
" bytesToCompare: "
+
bytesToCompare
);
for
(
int
i
=
0
;
i
<
bytesToCompare
;
i
++)
{
int
setA
=
i
+
offsetA
;
int
setB
=
i
+
offsetB
;
if
(
setA
>
A
.
length
-
1
||
setB
>
B
.
length
-
1
||
A
[
setA
]
!=
B
[
setB
])
{
return
false
;
}
}
return
true
;
}
/*
* Creates a Cipher object for testing: for encryption it creates new Cipher
* based on previously saved parameters (it is prohibited to use the same
* Cipher twice for encription during GCM mode), or returns initiated
* existing Cipher.
*/
private
Cipher
createCipher
(
int
mode
,
AlgorithmParameters
params
)
throws
Exception
{
Cipher
cipher
=
Cipher
.
getInstance
(
transformation
,
provider
);
if
(
Cipher
.
ENCRYPT_MODE
==
mode
)
{
// initiate it with the saved parameters
if
(
params
!=
null
)
{
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
,
params
);
}
else
{
// intiate the cipher and save parameters
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
}
}
else
if
(
cipher
!=
null
)
{
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key
,
params
);
}
else
{
throw
new
RuntimeException
(
"Can't create cipher"
);
}
return
cipher
;
}
}
test/com/sun/crypto/provider/Cipher/AEAD/SealedObjectTest.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.security.AlgorithmParameters
;
import
java.util.Arrays
;
import
javax.crypto.SecretKey
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
import
javax.crypto.SealedObject
;
/*
* @test
* @bug 8048596
* @summary Check if the seal/unseal feature works properly in AEAD/GCM mode.
*/
public
class
SealedObjectTest
{
private
static
final
String
AES
=
"AES"
;
private
static
final
String
TRANSFORMATION
=
"AES/GCM/NoPadding"
;
private
static
final
String
PROVIDER
=
"SunJCE"
;
private
static
final
int
KEY_LENGTH
=
128
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
doTest
();
}
/*
* Run the test:
* - init a cipher with AES/GCM/NoPadding transformation
* - seal an object
* - check if we can't seal it again with the same key/IV
* - unseal the object using different methods of SealedObject class
* - check if the original and sealed objects are equal
*/
static
void
doTest
()
throws
Exception
{
// init a secret Key
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
AES
,
PROVIDER
);
kg
.
init
(
KEY_LENGTH
);
SecretKey
key
=
kg
.
generateKey
();
// initialization
Cipher
cipher
=
Cipher
.
getInstance
(
TRANSFORMATION
,
PROVIDER
);
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
key
);
AlgorithmParameters
params
=
cipher
.
getParameters
();
// seal an object
SealedObject
so
=
new
SealedObject
(
key
,
cipher
);
try
{
// check if we can't seal it again with the same key/IV
so
=
new
SealedObject
(
key
,
cipher
);
throw
new
RuntimeException
(
"FAILED: expected IllegalStateException hasn't "
+
"been thrown"
);
}
catch
(
IllegalStateException
ise
)
{
System
.
out
.
println
(
"Expected exception when seal it again with"
+
" the same key/IV: "
+
ise
);
}
// unseal the object using getObject(Cipher) and compare
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
key
,
params
);
SecretKey
unsealedKey
=
(
SecretKey
)
so
.
getObject
(
cipher
);
assertKeysSame
(
unsealedKey
,
key
,
"SealedObject.getObject(Cipher)"
);
// unseal the object using getObject(Key) and compare
unsealedKey
=
(
SecretKey
)
so
.
getObject
(
key
);
assertKeysSame
(
unsealedKey
,
key
,
"SealedObject.getObject(Key)"
);
// unseal the object using getObject(Key, String) and compare
unsealedKey
=
(
SecretKey
)
so
.
getObject
(
key
,
PROVIDER
);
assertKeysSame
(
unsealedKey
,
key
,
"SealedObject.getObject(Key, String)"
);
}
/**
* Compare two SecretKey objects.
*
* @param key1 first key
* @param key2 second key
* @param meth method that was used for unsealing the SecretKey object
* @return true if key1 and key2 are the same, false otherwise.
*/
static
void
assertKeysSame
(
SecretKey
key1
,
SecretKey
key2
,
String
meth
)
{
if
(!
Arrays
.
equals
(
key1
.
getEncoded
(),
key2
.
getEncoded
()))
{
throw
new
RuntimeException
(
"FAILED: original and unsealed objects aren't the same for "
+
meth
);
}
}
}
test/com/sun/crypto/provider/Cipher/AEAD/WrongAAD.java
0 → 100644
浏览文件 @
da6c04b0
/*
* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.ByteArrayInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.security.AlgorithmParameters
;
import
java.security.InvalidAlgorithmParameterException
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.NoSuchProviderException
;
import
java.util.Arrays
;
import
javax.crypto.CipherInputStream
;
import
javax.crypto.CipherOutputStream
;
import
javax.crypto.NoSuchPaddingException
;
import
javax.crypto.SecretKey
;
import
javax.crypto.Cipher
;
import
javax.crypto.KeyGenerator
;
/*
* @test
* @bug 8048596
* @summary Check if wrong or empty AAD is rejected
*/
public
class
WrongAAD
{
private
static
final
String
PROVIDER
=
"SunJCE"
;
private
static
final
String
TRANSFORMATION
=
"AES/GCM/NoPadding"
;
private
static
final
int
TEXT_SIZE
=
800
;
private
static
final
int
KEY_SIZE
=
128
;
private
static
final
int
AAD_SIZE
=
128
;
private
final
SecretKey
key
;
private
final
byte
[]
plainText
;
private
final
Cipher
encryptCipher
;
public
WrongAAD
()
throws
Exception
{
// init a secret key
KeyGenerator
kg
=
KeyGenerator
.
getInstance
(
"AES"
,
PROVIDER
);
kg
.
init
(
KEY_SIZE
);
key
=
kg
.
generateKey
();
// generate a plain text
plainText
=
Helper
.
generateBytes
(
TEXT_SIZE
);
// init AADs
byte
[]
AAD
=
Helper
.
generateBytes
(
AAD_SIZE
);
// init a cipher
encryptCipher
=
createCipher
(
Cipher
.
ENCRYPT_MODE
,
null
);
encryptCipher
.
updateAAD
(
AAD
);
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
WrongAAD
test
=
new
WrongAAD
();
test
.
decryptWithEmptyAAD
();
test
.
decryptWithWrongAAD
();
}
/*
* Attempt to decrypt a cipher text using Cipher object
* initialized without AAD used for encryption.
*/
private
void
decryptWithEmptyAAD
()
throws
Exception
{
System
.
out
.
println
(
"decryptWithEmptyAAD() started"
);
// initialize it with empty AAD to get exception during decryption
Cipher
decryptCipher
=
createCipher
(
Cipher
.
DECRYPT_MODE
,
encryptCipher
.
getParameters
());
try
(
ByteArrayOutputStream
baOutput
=
new
ByteArrayOutputStream
();
CipherOutputStream
ciOutput
=
new
CipherOutputStream
(
baOutput
,
decryptCipher
))
{
if
(
decrypt
(
ciOutput
,
baOutput
))
{
throw
new
RuntimeException
(
"Decryption has been perfomed successfully in"
+
" spite of the decrypt Cipher has NOT been"
+
" initialized with AAD"
);
}
}
System
.
out
.
println
(
"decryptWithEmptyAAD() passed"
);
}
/*
* Attempt to decrypt the cipher text using Cipher object
* initialized with some fake AAD.
*/
private
void
decryptWithWrongAAD
()
throws
Exception
{
System
.
out
.
println
(
"decrypt with wrong AAD"
);
// initialize it with wrong AAD to get an exception during decryption
Cipher
decryptCipher
=
createCipher
(
Cipher
.
DECRYPT_MODE
,
encryptCipher
.
getParameters
());
byte
[]
someAAD
=
Helper
.
generateBytes
(
AAD_SIZE
+
1
);
decryptCipher
.
updateAAD
(
someAAD
);
// init output stream
try
(
ByteArrayOutputStream
baOutput
=
new
ByteArrayOutputStream
();
CipherOutputStream
ciOutput
=
new
CipherOutputStream
(
baOutput
,
decryptCipher
);)
{
if
(
decrypt
(
ciOutput
,
baOutput
))
{
throw
new
RuntimeException
(
"A decryption has been perfomed successfully in"
+
" spite of the decrypt Cipher has been"
+
" initialized with fake AAD"
);
}
}
System
.
out
.
println
(
"Passed"
);
}
private
boolean
decrypt
(
CipherOutputStream
ciOutput
,
ByteArrayOutputStream
baOutput
)
throws
IOException
{
try
(
ByteArrayInputStream
baInput
=
new
ByteArrayInputStream
(
plainText
);
CipherInputStream
ciInput
=
new
CipherInputStream
(
baInput
,
encryptCipher
))
{
byte
[]
buffer
=
new
byte
[
TEXT_SIZE
];
int
len
=
ciInput
.
read
(
buffer
);
while
(
len
!=
-
1
)
{
ciOutput
.
write
(
buffer
,
0
,
len
);
len
=
ciInput
.
read
(
buffer
);
}
ciOutput
.
flush
();
byte
[]
recoveredText
=
baOutput
.
toByteArray
();
System
.
out
.
println
(
"recoveredText: "
+
new
String
(
recoveredText
));
/*
* See bug 8012900, AEADBadTagException is swalloed by CI/CO streams
* If recovered text is empty, than decryption failed
*/
if
(
recoveredText
.
length
==
0
)
{
return
false
;
}
return
Arrays
.
equals
(
plainText
,
recoveredText
);
}
catch
(
IllegalStateException
e
)
{
System
.
out
.
println
(
"Expected IllegalStateException: "
+
e
.
getMessage
());
e
.
printStackTrace
(
System
.
out
);
return
false
;
}
}
private
Cipher
createCipher
(
int
mode
,
AlgorithmParameters
params
)
throws
NoSuchAlgorithmException
,
NoSuchProviderException
,
NoSuchPaddingException
,
InvalidKeyException
,
InvalidAlgorithmParameterException
{
Cipher
cipher
=
Cipher
.
getInstance
(
TRANSFORMATION
,
PROVIDER
);
if
(
params
!=
null
)
{
cipher
.
init
(
mode
,
key
,
params
);
}
else
{
cipher
.
init
(
mode
,
key
);
}
return
cipher
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录