/* * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.crypto.provider; import java.io.IOException; import java.security.AlgorithmParametersSpi; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import sun.security.util.*; /** * This class implements the parameter set used with the ChaCha20-Poly1305 * algorithm. The parameter definition comes from * RFC 8103 * and is defined according to the following ASN.1: * *
* id-alg-AEADChaCha20Poly1305 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) alg(3) 18 } * AEADChaCha20Poly1305Nonce ::= OCTET STRING (SIZE(12)) ** * The AlgorithmParameters may be instantiated either by its name * ("ChaCha20-Poly1305") or via its OID (1.2.840.113549.1.9.16.3.18) * * @since 11 */ public final class ChaCha20Poly1305Parameters extends AlgorithmParametersSpi { private static final String DEFAULT_FMT = "ASN.1"; private byte[] nonce; public ChaCha20Poly1305Parameters() {} /** * Initialize the ChaCha20Poly1305Parameters using an IvParameterSpec. * * @param paramSpec the {@code IvParameterSpec} used to configure * this object. * * @throws InvalidParameterSpecException if an object of a type other * than {@code IvParameterSpec} is used. */ @Override protected void engineInit(AlgorithmParameterSpec paramSpec) throws InvalidParameterSpecException { if (!(paramSpec instanceof IvParameterSpec)) { throw new InvalidParameterSpecException ("Inappropriate parameter specification"); } IvParameterSpec ivps = (IvParameterSpec)paramSpec; // Obtain the nonce nonce = ivps.getIV(); if (nonce.length != 12) { throw new InvalidParameterSpecException("ChaCha20-Poly1305 nonce" + " must be 96 bits in length"); } } /** * Initialize the ChaCha20Poly1305Parameters from a DER encoded * parameter block. * @param encoded the DER encoding of the nonce as an OCTET STRING. * * @throws IOException if the encoded nonce is not 12 bytes long or a DER * decoding error occurs. */ @Override protected void engineInit(byte[] encoded) throws IOException { DerValue val = new DerValue(encoded); // Make sure we're dealing with an OCTET STRING if (val.tag == DerValue.tag_OctetString) { // Get the nonce value nonce = val.getOctetString(); if (nonce.length != 12) { throw new IOException( "ChaCha20-Poly1305 nonce must be 96 bits in length"); } } else { throw new IOException( "ChaCha20-Poly1305 Parameter ASN.1 encoding error"); } } /** * Initialize the ChaCha20Poly1305Parameters from a DER encoded * parameter block. * * @param encoded the DER encoding of the nonce and initial block counter. * @param decodingMethod the decoding method. The only currently accepted * value is "ASN.1" * * @throws IOException if the encoded nonce is not 12 bytes long or a DER * decoding error occurs. * @throws IllegalArgumentException if the decodingMethod parameter does * not specify a supported format. */ @Override protected void engineInit(byte[] encoded, String decodingMethod) throws IOException { if (decodingMethod.equalsIgnoreCase(DEFAULT_FMT)) { engineInit(encoded); } else { throw new IllegalArgumentException( "Unsupported parameter format: " + decodingMethod); } } /** * Return an IvParameterSpec with the same parameters as those * held in this object. * * @param paramSpec the class name of the spec. In this case it should * be {@code IvParameterSpec.class}. * * @return a {@code IvParameterSpec} object containing the nonce * value held in this object. * * @throws InvalidParameterSpecException if a class other than * {@code IvParameterSpec.class} was specified in the paramSpec * parameter. */ @Override protected