1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package org.conscrypt; 18 19import java.io.IOException; 20import java.security.AlgorithmParametersSpi; 21import java.security.spec.AlgorithmParameterSpec; 22import java.security.spec.InvalidParameterSpecException; 23import javax.crypto.spec.IvParameterSpec; 24 25/** 26 * An implementation of {@link java.security.AlgorithmParameters} that contains only an IV. The 27 * supported encoding formats are ASN.1 (primary) and RAW. 28 * 29 * @hide 30 */ 31@Internal 32public class IvParameters extends AlgorithmParametersSpi { 33 private byte[] iv; 34 35 @Override 36 protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec) 37 throws InvalidParameterSpecException { 38 if (!(algorithmParameterSpec instanceof IvParameterSpec)) { 39 throw new InvalidParameterSpecException("Only IvParameterSpec is supported"); 40 } 41 iv = ((IvParameterSpec) algorithmParameterSpec).getIV().clone(); 42 } 43 44 @Override 45 protected void engineInit(byte[] bytes) throws IOException { 46 long readRef = 0; 47 try { 48 readRef = NativeCrypto.asn1_read_init(bytes); 49 byte[] newIv = NativeCrypto.asn1_read_octetstring(readRef); 50 if (!NativeCrypto.asn1_read_is_empty(readRef)) { 51 throw new IOException("Error reading ASN.1 encoding"); 52 } 53 this.iv = newIv; 54 } finally { 55 NativeCrypto.asn1_read_free(readRef); 56 } 57 } 58 59 @Override 60 protected void engineInit(byte[] bytes, String format) throws IOException { 61 if (format == null || format.equals("ASN.1")) { 62 engineInit(bytes); 63 } else if (format.equals("RAW")) { 64 iv = bytes.clone(); 65 } else { 66 throw new IOException("Unsupported format: " + format); 67 } 68 } 69 70 @Override 71 @SuppressWarnings("unchecked") 72 protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> aClass) 73 throws InvalidParameterSpecException { 74 if (aClass != IvParameterSpec.class) { 75 throw new InvalidParameterSpecException( 76 "Incompatible AlgorithmParametersSpec class: " + aClass); 77 } 78 return (T) new IvParameterSpec(iv); 79 } 80 81 @Override 82 protected byte[] engineGetEncoded() throws IOException { 83 long cbbRef = 0; 84 try { 85 cbbRef = NativeCrypto.asn1_write_init(); 86 NativeCrypto.asn1_write_octetstring(cbbRef, this.iv); 87 return NativeCrypto.asn1_write_finish(cbbRef); 88 } catch (IOException e) { 89 NativeCrypto.asn1_write_cleanup(cbbRef); 90 throw e; 91 } finally { 92 NativeCrypto.asn1_write_free(cbbRef); 93 } 94 } 95 96 @Override 97 protected byte[] engineGetEncoded(String format) throws IOException { 98 if (format == null || format.equals("ASN.1")) { 99 return engineGetEncoded(); 100 } else if (format.equals("RAW")) { 101 return iv.clone(); 102 } else { 103 throw new IOException("Unsupported format: " + format); 104 } 105 } 106 107 @Override 108 protected String engineToString() { 109 return "Conscrypt IV AlgorithmParameters"; 110 } 111 112 public static class AES extends IvParameters {} 113 public static class DESEDE extends IvParameters {} 114 public static class ChaCha20 extends IvParameters {} 115} 116