Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.crypto.ec/share/classes/sun/security/ec/XDHKeyAgreement.java
41161 views
1
/*
2
* Copyright (c) 2018, 2019, 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 sun.security.ec;
27
28
import java.security.InvalidAlgorithmParameterException;
29
import java.security.InvalidKeyException;
30
import java.security.NoSuchAlgorithmException;
31
import java.security.Key;
32
import java.security.SecureRandom;
33
import java.security.ProviderException;
34
import java.security.interfaces.XECPrivateKey;
35
import java.security.interfaces.XECPublicKey;
36
import java.security.spec.AlgorithmParameterSpec;
37
import java.security.spec.NamedParameterSpec;
38
import javax.crypto.KeyAgreementSpi;
39
import javax.crypto.SecretKey;
40
import javax.crypto.ShortBufferException;
41
import javax.crypto.spec.SecretKeySpec;
42
import java.util.function.Function;
43
44
public class XDHKeyAgreement extends KeyAgreementSpi {
45
46
private byte[] privateKey;
47
private byte[] secret;
48
private XECOperations ops;
49
private XECParameters lockedParams = null;
50
51
XDHKeyAgreement() {
52
// do nothing
53
}
54
55
XDHKeyAgreement(AlgorithmParameterSpec paramSpec) {
56
lockedParams = XECParameters.get(ProviderException::new, paramSpec);
57
}
58
59
@Override
60
protected void engineInit(Key key, SecureRandom random)
61
throws InvalidKeyException {
62
63
initImpl(key);
64
}
65
66
@Override
67
protected void engineInit(Key key, final AlgorithmParameterSpec params,
68
SecureRandom random) throws InvalidKeyException,
69
InvalidAlgorithmParameterException {
70
71
initImpl(key);
72
73
// the private key parameters must match params, if present
74
if (params != null) {
75
XECParameters xecParams = XECParameters.get(
76
InvalidAlgorithmParameterException::new, params);
77
if (!xecParams.oidEquals(this.ops.getParameters())) {
78
throw new InvalidKeyException(
79
"Incorrect private key parameters"
80
);
81
}
82
}
83
}
84
85
private
86
<T extends Throwable>
87
void checkLockedParams(Function<String, T> exception,
88
XECParameters params) throws T {
89
90
if (lockedParams != null && lockedParams != params) {
91
throw exception.apply("Parameters must be " +
92
lockedParams.getName());
93
}
94
}
95
96
private void initImpl(Key key) throws InvalidKeyException {
97
98
if (!(key instanceof XECPrivateKey)) {
99
throw new InvalidKeyException
100
("Unsupported key type");
101
}
102
XECPrivateKey privateKey = (XECPrivateKey) key;
103
XECParameters xecParams = XECParameters.get(
104
InvalidKeyException::new, privateKey.getParams());
105
checkLockedParams(InvalidKeyException::new, xecParams);
106
107
this.ops = new XECOperations(xecParams);
108
this.privateKey = privateKey.getScalar().orElseThrow(
109
() -> new InvalidKeyException("No private key value")
110
);
111
secret = null;
112
}
113
114
@Override
115
protected Key engineDoPhase(Key key, boolean lastPhase)
116
throws InvalidKeyException, IllegalStateException {
117
118
if (this.privateKey == null) {
119
throw new IllegalStateException("Not initialized");
120
}
121
if (this.secret != null) {
122
throw new IllegalStateException("Phase already executed");
123
}
124
if (!lastPhase) {
125
throw new IllegalStateException
126
("Only two party agreement supported, lastPhase must be true");
127
}
128
if (!(key instanceof XECPublicKey)) {
129
throw new InvalidKeyException
130
("Unsupported key type");
131
}
132
133
XECPublicKey publicKey = (XECPublicKey) key;
134
135
// Ensure public key parameters are compatible with private key
136
XECParameters xecParams = XECParameters.get(InvalidKeyException::new,
137
publicKey.getParams());
138
if (!ops.getParameters().oidEquals(xecParams)) {
139
throw new InvalidKeyException(
140
"Public key parameters are not compatible with private key.");
141
}
142
143
// The privateKey may be modified to a value that is equivalent for
144
// the purposes of this algorithm.
145
byte[] computedSecret = ops.encodedPointMultiply(
146
this.privateKey,
147
publicKey.getU());
148
149
// test for contributory behavior
150
if (allZero(computedSecret)) {
151
throw new InvalidKeyException("Point has small order");
152
}
153
154
this.secret = computedSecret;
155
156
return null;
157
}
158
159
/*
160
* Constant-time check for an all-zero array
161
*/
162
private boolean allZero(byte[] arr) {
163
byte orValue = (byte) 0;
164
for (int i = 0; i < arr.length; i++) {
165
orValue |= arr[i];
166
}
167
168
return orValue == (byte) 0;
169
}
170
171
@Override
172
protected byte[] engineGenerateSecret() throws IllegalStateException {
173
if (secret == null) {
174
throw new IllegalStateException("Not initialized correctly");
175
}
176
177
byte[] result = secret;
178
secret = null;
179
return result;
180
}
181
182
@Override
183
protected int engineGenerateSecret(byte[] sharedSecret, int offset)
184
throws IllegalStateException, ShortBufferException {
185
186
if (secret == null) {
187
throw new IllegalStateException("Not initialized correctly");
188
}
189
int secretLen = this.secret.length;
190
if (secretLen > sharedSecret.length - offset) {
191
throw new ShortBufferException("Need " + secretLen
192
+ " bytes, only " + (sharedSecret.length - offset)
193
+ " available");
194
}
195
196
System.arraycopy(this.secret, 0, sharedSecret, offset, secretLen);
197
secret = null;
198
return secretLen;
199
}
200
201
@Override
202
protected SecretKey engineGenerateSecret(String algorithm)
203
throws IllegalStateException, NoSuchAlgorithmException,
204
InvalidKeyException {
205
206
if (algorithm == null) {
207
throw new NoSuchAlgorithmException("Algorithm must not be null");
208
}
209
210
if (!(algorithm.equals("TlsPremasterSecret"))) {
211
throw new NoSuchAlgorithmException(
212
"Only supported for algorithm TlsPremasterSecret");
213
}
214
return new SecretKeySpec(engineGenerateSecret(), algorithm);
215
}
216
217
static class X25519 extends XDHKeyAgreement {
218
219
public X25519() {
220
super(NamedParameterSpec.X25519);
221
}
222
}
223
224
static class X448 extends XDHKeyAgreement {
225
226
public X448() {
227
super(NamedParameterSpec.X448);
228
}
229
}
230
}
231
232