1 /* 2 * Copyright (c) 2018, 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 sun.security.ec; 27 28 import java.math.BigInteger; 29 import java.security.KeyPairGeneratorSpi; 30 import java.security.InvalidKeyException; 31 import java.security.InvalidParameterException; 32 import java.security.InvalidAlgorithmParameterException; 33 import java.security.KeyPair; 34 import java.security.ProviderException; 35 import java.security.SecureRandom; 36 import java.security.spec.AlgorithmParameterSpec; 37 import java.security.spec.NamedParameterSpec; 38 import java.util.Arrays; 39 40 import sun.security.jca.JCAUtil; 41 42 /** 43 * Key pair generator for the XDH key agreement algorithm. 44 */ 45 public class XDHKeyPairGenerator extends KeyPairGeneratorSpi { 46 47 private static final NamedParameterSpec DEFAULT_PARAM_SPEC 48 = NamedParameterSpec.X25519; 49 50 private SecureRandom random = null; 51 private XECOperations ops = null; 52 private XECParameters lockedParams = null; 53 XDHKeyPairGenerator()54 XDHKeyPairGenerator() { 55 tryInitialize(DEFAULT_PARAM_SPEC); 56 } 57 XDHKeyPairGenerator(NamedParameterSpec paramSpec)58 private XDHKeyPairGenerator(NamedParameterSpec paramSpec) { 59 tryInitialize(paramSpec); 60 lockedParams = ops.getParameters(); 61 } 62 tryInitialize(NamedParameterSpec paramSpec)63 private void tryInitialize(NamedParameterSpec paramSpec) { 64 try { 65 initialize(paramSpec, null); 66 } catch (InvalidAlgorithmParameterException ex) { 67 String name = paramSpec.getName(); 68 throw new ProviderException(name + " not supported"); 69 } 70 } 71 72 @Override initialize(int keySize, SecureRandom random)73 public void initialize(int keySize, SecureRandom random) { 74 75 XECParameters params = XECParameters.getBySize( 76 InvalidParameterException::new, keySize); 77 78 initializeImpl(params, random); 79 } 80 81 @Override initialize(AlgorithmParameterSpec params, SecureRandom random)82 public void initialize(AlgorithmParameterSpec params, SecureRandom random) 83 throws InvalidAlgorithmParameterException { 84 85 XECParameters xecParams = XECParameters.get( 86 InvalidAlgorithmParameterException::new, params); 87 88 initializeImpl(xecParams, random); 89 } 90 initializeImpl(XECParameters params, SecureRandom random)91 private void initializeImpl(XECParameters params, SecureRandom random) { 92 93 if (lockedParams != null && lockedParams != params) { 94 throw new InvalidParameterException("Parameters must be " + 95 lockedParams.getName()); 96 } 97 98 this.ops = new XECOperations(params); 99 this.random = random == null ? JCAUtil.getSecureRandom() : random; 100 } 101 102 103 @Override generateKeyPair()104 public KeyPair generateKeyPair() { 105 106 byte[] privateKey = ops.generatePrivate(random); 107 // computePublic may modify the private key, so clone it first 108 byte[] cloned = privateKey.clone(); 109 BigInteger publicKey = ops.computePublic(cloned); 110 Arrays.fill(cloned, (byte)0); 111 112 try { 113 return new KeyPair( 114 new XDHPublicKeyImpl(ops.getParameters(), publicKey), 115 new XDHPrivateKeyImpl(ops.getParameters(), privateKey) 116 ); 117 } catch (InvalidKeyException ex) { 118 throw new ProviderException(ex); 119 } finally { 120 Arrays.fill(privateKey, (byte)0); 121 } 122 } 123 124 static class X25519 extends XDHKeyPairGenerator { 125 X25519()126 public X25519() { 127 super(NamedParameterSpec.X25519); 128 } 129 } 130 131 static class X448 extends XDHKeyPairGenerator { 132 X448()133 public X448() { 134 super(NamedParameterSpec.X448); 135 } 136 } 137 } 138