1 /* 2 * Copyright (c) 1998, 2007, 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 javax.crypto; 27 28 import java.security.*; 29 import java.security.spec.*; 30 31 import java.nio.ByteBuffer; 32 33 /** 34 * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) 35 * for the <code>Mac</code> class. 36 * All the abstract methods in this class must be implemented by each 37 * cryptographic service provider who wishes to supply the implementation 38 * of a particular MAC algorithm. 39 * 40 * <p> Implementations are free to implement the Cloneable interface. 41 * 42 * @author Jan Luehe 43 * 44 * @since 1.4 45 */ 46 47 public abstract class MacSpi { 48 49 /** 50 * Returns the length of the MAC in bytes. 51 * 52 * @return the MAC length in bytes. 53 */ engineGetMacLength()54 protected abstract int engineGetMacLength(); 55 56 /** 57 * Initializes the MAC with the given (secret) key and algorithm 58 * parameters. 59 * 60 * @param key the (secret) key. 61 * @param params the algorithm parameters. 62 * 63 * @exception InvalidKeyException if the given key is inappropriate for 64 * initializing this MAC. 65 * @exception InvalidAlgorithmParameterException if the given algorithm 66 * parameters are inappropriate for this MAC. 67 */ engineInit(Key key, AlgorithmParameterSpec params)68 protected abstract void engineInit(Key key, 69 AlgorithmParameterSpec params) 70 throws InvalidKeyException, InvalidAlgorithmParameterException ; 71 72 /** 73 * Processes the given byte. 74 * 75 * @param input the input byte to be processed. 76 */ engineUpdate(byte input)77 protected abstract void engineUpdate(byte input); 78 79 /** 80 * Processes the first <code>len</code> bytes in <code>input</code>, 81 * starting at <code>offset</code> inclusive. 82 * 83 * @param input the input buffer. 84 * @param offset the offset in <code>input</code> where the input starts. 85 * @param len the number of bytes to process. 86 */ engineUpdate(byte[] input, int offset, int len)87 protected abstract void engineUpdate(byte[] input, int offset, int len); 88 89 /** 90 * Processes <code>input.remaining()</code> bytes in the ByteBuffer 91 * <code>input</code>, starting at <code>input.position()</code>. 92 * Upon return, the buffer's position will be equal to its limit; 93 * its limit will not have changed. 94 * 95 * <p>Subclasses should consider overriding this method if they can 96 * process ByteBuffers more efficiently than byte arrays. 97 * 98 * @param input the ByteBuffer 99 * @since 1.5 100 */ engineUpdate(ByteBuffer input)101 protected void engineUpdate(ByteBuffer input) { 102 if (input.hasRemaining() == false) { 103 return; 104 } 105 if (input.hasArray()) { 106 byte[] b = input.array(); 107 int ofs = input.arrayOffset(); 108 int pos = input.position(); 109 int lim = input.limit(); 110 engineUpdate(b, ofs + pos, lim - pos); 111 input.position(lim); 112 } else { 113 int len = input.remaining(); 114 byte[] b = new byte[CipherSpi.getTempArraySize(len)]; 115 while (len > 0) { 116 int chunk = Math.min(len, b.length); 117 input.get(b, 0, chunk); 118 engineUpdate(b, 0, chunk); 119 len -= chunk; 120 } 121 } 122 } 123 124 /** 125 * Completes the MAC computation and resets the MAC for further use, 126 * maintaining the secret key that the MAC was initialized with. 127 * 128 * @return the MAC result. 129 */ engineDoFinal()130 protected abstract byte[] engineDoFinal(); 131 132 /** 133 * Resets the MAC for further use, maintaining the secret key that the 134 * MAC was initialized with. 135 */ engineReset()136 protected abstract void engineReset(); 137 138 /** 139 * Returns a clone if the implementation is cloneable. 140 * 141 * @return a clone if the implementation is cloneable. 142 * 143 * @exception CloneNotSupportedException if this is called 144 * on an implementation that does not support <code>Cloneable</code>. 145 */ clone()146 public Object clone() throws CloneNotSupportedException { 147 if (this instanceof Cloneable) { 148 return super.clone(); 149 } else { 150 throw new CloneNotSupportedException(); 151 } 152 } 153 } 154