Path: blob/master/src/java.base/share/classes/sun/security/util/GCMParameters.java
41159 views
/*1* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.util;2627import java.io.IOException;28import java.security.AlgorithmParametersSpi;29import java.security.spec.AlgorithmParameterSpec;30import java.security.spec.InvalidParameterSpecException;31import javax.crypto.spec.GCMParameterSpec;32import sun.security.util.HexDumpEncoder;33import sun.security.util.*;3435/**36* This class implements the parameter set used with37* GCM encryption, which is defined in RFC 5084 as follows:38*39* <pre>40* GCMParameters ::= SEQUENCE {41* aes-iv OCTET STRING, -- recommended size is 12 octets42* aes-tLen AES-GCM-ICVlen DEFAULT 12 }43*44* AES-GCM-ICVlen ::= INTEGER (12 | 13 | 14 | 15 | 16)45*46* </pre>47*48* @since 1349*/50public final class GCMParameters extends AlgorithmParametersSpi {5152// the iv53private byte[] iv;54// the tag length in bytes55private int tLen;5657public GCMParameters() {}5859protected void engineInit(AlgorithmParameterSpec paramSpec)60throws InvalidParameterSpecException {6162if (!(paramSpec instanceof GCMParameterSpec)) {63throw new InvalidParameterSpecException64("Inappropriate parameter specification");65}66GCMParameterSpec gps = (GCMParameterSpec) paramSpec;67// need to convert from bits to bytes for ASN.1 encoding68this.tLen = gps.getTLen()/8;69if (this.tLen < 12 || this.tLen > 16 ) {70throw new InvalidParameterSpecException71("GCM parameter parsing error: unsupported tag len: " +72this.tLen);73}74this.iv = gps.getIV();75}7677protected void engineInit(byte[] encoded) throws IOException {78DerValue val = new DerValue(encoded);79// check if IV or params80if (val.tag == DerValue.tag_Sequence) {81byte[] iv = val.data.getOctetString();82int tLen;83if (val.data.available() != 0) {84tLen = val.data.getInteger();85if (tLen < 12 || tLen > 16 ) {86throw new IOException87("GCM parameter parsing error: unsupported tag len: " +88tLen);89}90if (val.data.available() != 0) {91throw new IOException92("GCM parameter parsing error: extra data");93}94} else {95tLen = 12;96}97this.iv = iv.clone();98this.tLen = tLen;99} else {100throw new IOException("GCM parameter parsing error: no SEQ tag");101}102}103104protected void engineInit(byte[] encoded, String decodingMethod)105throws IOException {106engineInit(encoded);107}108109protected <T extends AlgorithmParameterSpec>110T engineGetParameterSpec(Class<T> paramSpec)111throws InvalidParameterSpecException {112113if (GCMParameterSpec.class.isAssignableFrom(paramSpec)) {114return paramSpec.cast(new GCMParameterSpec(tLen * 8, iv));115} else {116throw new InvalidParameterSpecException117("Inappropriate parameter specification");118}119}120121protected byte[] engineGetEncoded() throws IOException {122DerOutputStream out = new DerOutputStream();123DerOutputStream bytes = new DerOutputStream();124125bytes.putOctetString(iv);126// Only put non-default values127if (tLen != 12) {128bytes.putInteger(tLen);129}130out.write(DerValue.tag_Sequence, bytes);131return out.toByteArray();132}133134protected byte[] engineGetEncoded(String encodingMethod)135throws IOException {136return engineGetEncoded();137}138139/*140* Returns a formatted string describing the parameters.141*/142protected String engineToString() {143String LINE_SEP = System.lineSeparator();144HexDumpEncoder encoder = new HexDumpEncoder();145StringBuilder sb146= new StringBuilder(LINE_SEP + " iv:" + LINE_SEP + "["147+ encoder.encodeBuffer(iv) + "]");148149sb.append(LINE_SEP + "tLen(bits):" + LINE_SEP + tLen*8 + LINE_SEP);150return sb.toString();151}152}153154155