1 /* 2 * Copyright (c) 1997, 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 com.sun.crypto.provider; 27 28 import java.security.InvalidKeyException; 29 import java.security.ProviderException; 30 import sun.security.util.ArrayUtil; 31 import java.util.Objects; 32 import jdk.internal.vm.annotation.IntrinsicCandidate; 33 34 /** 35 * This class represents ciphers in electronic codebook (ECB) mode. 36 * 37 * <p>This mode is implemented independently of a particular cipher. 38 * Ciphers to which this mode should apply (e.g., DES) must be 39 * <i>plugged-in</i> using the constructor. 40 * 41 * <p>NOTE: This class does not deal with buffering or padding. 42 * 43 * @author Gigi Ankeny 44 */ 45 46 final class ElectronicCodeBook extends FeedbackCipher { 47 ElectronicCodeBook(SymmetricCipher embeddedCipher)48 ElectronicCodeBook(SymmetricCipher embeddedCipher) { 49 super(embeddedCipher); 50 } 51 52 /** 53 * Gets the name of the feedback mechanism 54 * 55 * @return the name of the feedback mechanism 56 */ getFeedback()57 String getFeedback() { 58 return "ECB"; 59 } 60 61 /** 62 * Resets the iv to its original value. 63 * This is used when doFinal is called in the Cipher class, so that the 64 * cipher can be reused (with its original iv). 65 */ reset()66 void reset() { 67 // empty 68 } 69 70 /** 71 * Save the current content of this cipher. 72 */ save()73 void save() {} 74 75 /** 76 * Restores the content of this cipher to the previous saved one. 77 */ restore()78 void restore() {} 79 80 /** 81 * Initializes the cipher in the specified mode with the given key 82 * and iv. 83 * 84 * @param decrypting flag indicating encryption or decryption 85 * @param algorithm the algorithm name 86 * @param key the key 87 * @param iv the iv 88 * 89 * @exception InvalidKeyException if the given key is inappropriate for 90 * initializing this cipher 91 */ init(boolean decrypting, String algorithm, byte[] key, byte[] iv)92 void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) 93 throws InvalidKeyException { 94 if ((key == null) || (iv != null)) { 95 throw new InvalidKeyException("Internal error"); 96 } 97 embeddedCipher.init(decrypting, algorithm, key); 98 } 99 100 @IntrinsicCandidate implECBEncrypt(byte [] in, int inOff, int len, byte[] out, int outOff)101 private int implECBEncrypt(byte [] in, int inOff, int len, byte[] out, int outOff) { 102 for (int i = len; i >= blockSize; i -= blockSize) { 103 embeddedCipher.encryptBlock(in, inOff, out, outOff); 104 inOff += blockSize; 105 outOff += blockSize; 106 } 107 return len; 108 } 109 110 /** 111 * Performs encryption operation. 112 * 113 * <p>The input plain text <code>in</code>, starting at 114 * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>, 115 * is encrypted. The result is stored in <code>out</code>, starting at 116 * <code>outOff</code>. 117 * 118 * @param in the buffer with the input data to be encrypted 119 * @param inOff the offset in <code>plain</code> 120 * @param len the length of the input data 121 * @param out the buffer for the result 122 * @param outOff the offset in <code>cipher</code> 123 * @exception ProviderException if <code>len</code> is not 124 * a multiple of the block size 125 * @return the length of the encrypted data 126 */ encrypt(byte[] in, int inOff, int len, byte[] out, int outOff)127 int encrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { 128 ArrayUtil.blockSizeCheck(len, blockSize); 129 ArrayUtil.nullAndBoundsCheck(in, inOff, len); 130 ArrayUtil.nullAndBoundsCheck(out, outOff, len); 131 return implECBEncrypt(in, inOff, len, out, outOff); 132 } 133 134 @IntrinsicCandidate implECBDecrypt(byte [] in, int inOff, int len, byte[] out, int outOff)135 private int implECBDecrypt(byte [] in, int inOff, int len, byte[] out, int outOff) { 136 for (int i = len; i >= blockSize; i -= blockSize) { 137 embeddedCipher.decryptBlock(in, inOff, out, outOff); 138 inOff += blockSize; 139 outOff += blockSize; 140 } 141 return len; 142 } 143 144 /** 145 * Performs decryption operation. 146 * 147 * <p>The input cipher text <code>in</code>, starting at 148 * <code>inOff</code> and ending at * <code>(inOff + len - 1)</code>, 149 * is decrypted.The result is stored in <code>out</code>, starting at 150 * <code>outOff</code>. 151 * 152 * @param in the buffer with the input data to be decrypted 153 * @param inOff the offset in <code>cipherOffset</code> 154 * @param len the length of the input data 155 * @param out the buffer for the result 156 * @param outOff the offset in <code>plain</code> 157 * @exception ProviderException if <code>len</code> is not 158 * a multiple of the block size 159 * @return the length of the decrypted data 160 */ decrypt(byte[] in, int inOff, int len, byte[] out, int outOff)161 int decrypt(byte[] in, int inOff, int len, byte[] out, int outOff) { 162 ArrayUtil.blockSizeCheck(len, blockSize); 163 ArrayUtil.nullAndBoundsCheck(in, inOff, len); 164 ArrayUtil.nullAndBoundsCheck(out, outOff, len); 165 return implECBDecrypt(in, inOff, len, out, outOff); 166 } 167 } 168