Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/com/sun/crypto/provider/AESKeyWrap.java
41161 views
1
/*
2
* Copyright (c) 2021, 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
26
package com.sun.crypto.provider;
27
28
import java.util.Arrays;
29
import java.security.*;
30
import java.security.spec.*;
31
import javax.crypto.*;
32
import javax.crypto.spec.*;
33
import static com.sun.crypto.provider.KWUtil.*;
34
35
/**
36
* This class implement the AES KeyWrap mode of operation as defined in
37
* <a href=https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38F.pdf>
38
* "Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping"</a>
39
* and represents AES cipher in KW mode.
40
*/
41
class AESKeyWrap extends FeedbackCipher {
42
43
// default integrity check value (icv) if iv is not supplied
44
private static final byte[] ICV1 = { // SEMI_BLKSIZE long
45
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6,
46
(byte) 0xA6, (byte) 0xA6, (byte) 0xA6, (byte) 0xA6
47
};
48
49
AESKeyWrap() {
50
super(new AESCrypt());
51
}
52
53
/**
54
* Gets the name of this feedback mode.
55
*
56
* @return the string <code>KW</code>
57
*/
58
@Override
59
String getFeedback() {
60
return "KW";
61
}
62
63
/**
64
* Save the current content of this cipher.
65
*/
66
@Override
67
void save() {
68
throw new UnsupportedOperationException("save not supported");
69
};
70
71
/**
72
* Restores the content of this cipher to the previous saved one.
73
*/
74
@Override
75
void restore() {
76
throw new UnsupportedOperationException("restore not supported");
77
};
78
79
/**
80
* Initializes the cipher in the specified mode with the given key
81
* and iv.
82
*
83
* @param decrypting flag indicating encryption or decryption
84
* @param algorithm the algorithm name
85
* @param key the key
86
* @param iv the iv
87
*
88
* @exception InvalidKeyException if the given key is inappropriate for
89
* initializing this cipher
90
* @exception InvalidAlgorithmParameterException if the given iv is
91
* non-null and not the right length
92
*/
93
@Override
94
void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
95
throws InvalidKeyException, InvalidAlgorithmParameterException {
96
if (key == null) {
97
throw new InvalidKeyException("Invalid null key");
98
}
99
if (iv != null && iv.length != SEMI_BLKSIZE) {
100
throw new InvalidAlgorithmParameterException("Invalid IV");
101
}
102
embeddedCipher.init(decrypting, algorithm, key);
103
// iv is retrieved from IvParameterSpec.getIV() which is already cloned
104
this.iv = (iv == null? ICV1 : iv);
105
}
106
107
/**
108
* Resets the iv to its original value.
109
* This is used when doFinal is called in the Cipher class, so that the
110
* cipher can be reused (with its original iv).
111
*/
112
@Override
113
void reset() {
114
throw new UnsupportedOperationException("reset not supported");
115
};
116
117
118
// no support for multi-part encryption
119
@Override
120
int encrypt(byte[] pt, int ptOfs, int ptLen, byte[] ct, int ctOfs) {
121
throw new UnsupportedOperationException("multi-part not supported");
122
};
123
124
// no support for multi-part decryption
125
@Override
126
int decrypt(byte[] ct, int ctOfs, int ctLen, byte[] pt, int ptOfs) {
127
throw new UnsupportedOperationException("multi-part not supported");
128
};
129
130
/**
131
* Performs single-part encryption operation.
132
*
133
* <p>The input <code>pt</code>, starting at <code>0</code>
134
* and ending at <code>ptLen-1</code>, is encrypted.
135
* The result is stored in place into <code>pt</code>, starting at
136
* <code>0</code>.
137
*
138
* <p>The subclass that implements Cipher should ensure that
139
* <code>init</code> has been called before this method is called.
140
*
141
* @param pt the input buffer with the data to be encrypted
142
* @param dummy1 the offset in <code>pt</code> which is always 0
143
* @param ptLen the length of the input data
144
* @param dummy2 the output buffer for the encryption which is always pt
145
* @param dummy3 the offset in the output buffer which is always 0
146
* @return the number of bytes placed into <code>pt</code>
147
*/
148
@Override
149
int encryptFinal(byte[] pt, int dummy1, int ptLen, byte[] dummy2,
150
int dummy3) throws IllegalBlockSizeException {
151
// adjust the min value since pt contains the first semi-block
152
if (ptLen < MIN_INPUTLEN || (ptLen % SEMI_BLKSIZE) != 0) {
153
throw new IllegalBlockSizeException("data should" +
154
" be at least 16 bytes and multiples of 8");
155
}
156
return W(iv, pt, ptLen, embeddedCipher);
157
}
158
159
/**
160
* Performs single-part decryption operation.
161
*
162
* <p>The input <code>ct</code>, starting at <code>0</code>
163
* and ending at <code>ctLen-1</code>, is decrypted.
164
* The result is stored in place into <code>ct</code>, starting at
165
* <code>0</code>.
166
*
167
* <p>NOTE: Purpose of this special impl is for minimizing array
168
* copying, those unused arguments are named as dummyN.
169
*
170
* <p>The subclass that implements Cipher should ensure that
171
* <code>init</code> has been called before this method is called.
172
*
173
* @param ct the input buffer with the data to be decrypted
174
* @param dummy1 the offset in <code>ct</code> which is always 0
175
* @param ctLen the length of the input data
176
* @param dummy2 the output buffer for the decryption which is always ct
177
* @param dummy3 the offset in the output buffer which is always 0
178
* @return the number of bytes placed into <code>ct</code>
179
*/
180
@Override
181
int decryptFinal(byte[] ct, int dummy1, int ctLen, byte[] dummy2,
182
int dummy3) throws IllegalBlockSizeException {
183
if (ctLen < MIN_INPUTLEN || (ctLen % SEMI_BLKSIZE) != 0) {
184
throw new IllegalBlockSizeException
185
("data should be at least 24 bytes and multiples of 8");
186
}
187
byte[] ivOut = new byte[SEMI_BLKSIZE];
188
ctLen = W_INV(ct, ctLen, ivOut, embeddedCipher);
189
190
// check against icv and fail if not match
191
if (!MessageDigest.isEqual(ivOut, this.iv)) {
192
throw new IllegalBlockSizeException("Integrity check failed");
193
}
194
return ctLen;
195
}
196
}
197
198