1 /*
2  * Copyright (c) 2018, 2020, 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.io.IOException;
29 import java.math.BigInteger;
30 import java.security.spec.AlgorithmParameterSpec;
31 import java.security.spec.NamedParameterSpec;
32 import java.util.Map;
33 import java.util.HashMap;
34 import java.util.function.Function;
35 
36 import sun.security.util.KnownOIDs;
37 import sun.security.util.ObjectIdentifier;
38 import sun.security.x509.AlgorithmId;
39 
40 public class XECParameters {
41 
42     static ParametersMap<XECParameters> namedParams = new ParametersMap<>();
43 
44     // Naming/identification parameters
45     private final ObjectIdentifier oid;
46     private final String name;
47 
48     // Curve/field parameters
49     private final int bits;
50     private final BigInteger p;
51     private final int logCofactor;
52     private final int a24;
53     private final byte basePoint;
54 
55     /**
56      *
57      * Construct an object holding the supplied parameters. No parameters are
58      * checked, so this method always succeeds. This method supports
59      * Montgomery curves of the form y^2 = x^3 + ax^2 + x.
60      *
61      * @param bits The number of relevant bits in a public/private key.
62      * @param p The prime that defines the finite field.
63      * @param a24 The value of (a - 2) / 4, where a is the second-degree curve
64      *            coefficient.
65      * @param basePoint The point that generates the desired group
66      * @param logCofactor The base-2 logarithm of the cofactor of the curve
67      * @param oid
68      * @param name
69      */
XECParameters(int bits, BigInteger p, int a24, byte basePoint, int logCofactor, ObjectIdentifier oid, String name)70     public XECParameters(int bits, BigInteger p, int a24,
71                          byte basePoint, int logCofactor,
72                          ObjectIdentifier oid, String name) {
73 
74         this.bits = bits;
75         this.logCofactor = logCofactor;
76         this.p = p;
77         this.a24 = a24;
78         this.basePoint = basePoint;
79         this.oid = oid;
80         this.name = name;
81 
82     }
83 
getBits()84     public int getBits() {
85         return bits;
86     }
getBytes()87     public int getBytes() {
88         return (bits + 7) / 8;
89     }
getLogCofactor()90     public int getLogCofactor() {
91         return logCofactor;
92     }
getP()93     public BigInteger getP() {
94         return p;
95     }
getA24()96     public int getA24() {
97         return a24;
98     }
getBasePoint()99     public byte getBasePoint() {
100         return basePoint;
101     }
getOid()102     public ObjectIdentifier getOid() {
103         return oid;
104     }
getName()105     public String getName() {
106         return name;
107     }
108 
109     static {
110         final BigInteger TWO = BigInteger.valueOf(2);
111 
112         Map<Integer, XECParameters> bySize = new HashMap<>();
113         Map<ObjectIdentifier, XECParameters> byOid = new HashMap<>();
114         Map<String, XECParameters> byName = new HashMap<>();
115 
116         // set up X25519
117         try {
118             BigInteger p = TWO.pow(255).subtract(BigInteger.valueOf(19));
119             addParameters(255, p, 121665, (byte)0x09, 3,
120                 KnownOIDs.X25519.value(), NamedParameterSpec.X25519.getName(),
121                 bySize, byOid, byName);
122 
123         } catch (IOException ex) {
124             // Unable to set X25519 parameters---it will be disabled
125         }
126 
127         // set up X448
128         try {
129             BigInteger p = TWO.pow(448).subtract(TWO.pow(224))
130                 .subtract(BigInteger.ONE);
131             addParameters(448, p, 39081, (byte)0x05, 2,
132                 KnownOIDs.X448.value(), NamedParameterSpec.X448.getName(),
133                 bySize, byOid, byName);
134 
135         } catch (IOException ex) {
136             // Unable to set X448 parameters---it will be disabled
137         }
138 
namedParams.fix()139         namedParams.fix();
140     }
141 
addParameters(int bits, BigInteger p, int a24, byte basePoint, int logCofactor, String objectId, String name, Map<Integer, XECParameters> bySize, Map<ObjectIdentifier, XECParameters> byOid, Map<String, XECParameters> byName)142     private static void addParameters(int bits, BigInteger p, int a24,
143         byte basePoint, int logCofactor, String objectId, String name,
144         Map<Integer, XECParameters> bySize,
145         Map<ObjectIdentifier, XECParameters> byOid,
146         Map<String, XECParameters> byName) throws IOException {
147 
148         ObjectIdentifier oid = ObjectIdentifier.of(objectId);
149         XECParameters params =
150             new XECParameters(bits, p, a24, basePoint, logCofactor, oid, name);
151         namedParams.put(name.toLowerCase(), oid, bits, params);
152     }
153 
oidEquals(XECParameters other)154     boolean oidEquals(XECParameters other) {
155         return oid.equals(other.getOid());
156     }
157 
158 
159     public static
160     <T extends Throwable>
getBySize(Function<String, T> exception, int size)161     XECParameters getBySize(Function<String, T> exception,
162                             int size) throws T {
163 
164         return namedParams.getBySize(exception, size);
165     }
166 
167     public static
168     <T extends Throwable>
get(Function<String, T> exception, AlgorithmId algId)169     XECParameters get(Function<String, T> exception,
170                       AlgorithmId algId) throws T {
171 
172         return namedParams.get(exception, algId);
173     }
174 
175     public static
176     <T extends Throwable>
get(Function<String, T> exception, AlgorithmParameterSpec params)177     XECParameters get(Function<String, T> exception,
178                       AlgorithmParameterSpec params) throws T {
179 
180         return namedParams.get(exception, params);
181     }
182 }
183 
184