Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java
38919 views
/*1* Copyright (c) 2003, 2021, 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.pkcs11;2627import java.io.IOException;28import java.math.BigInteger;29import java.nio.ByteBuffer;3031import java.security.*;32import java.security.interfaces.*;33import java.security.spec.AlgorithmParameterSpec;34import sun.nio.ch.DirectBuffer;3536import sun.security.util.*;37import sun.security.x509.AlgorithmId;3839import sun.security.rsa.RSASignature;40import sun.security.rsa.RSAPadding;4142import sun.security.pkcs11.wrapper.*;43import static sun.security.pkcs11.wrapper.PKCS11Constants.*;44import sun.security.util.KeyUtil;4546/**47* Signature implementation class. This class currently supports the48* following algorithms:49*50* . DSA51* . NONEwithDSA (RawDSA)52* . SHA1withDSA53* . RSA:54* . MD2withRSA55* . MD5withRSA56* . SHA1withRSA57* . SHA224withRSA58* . SHA256withRSA59* . SHA384withRSA60* . SHA512withRSA61* . ECDSA62* . NONEwithECDSA63* . SHA1withECDSA64* . SHA224withECDSA65* . SHA256withECDSA66* . SHA384withECDSA67* . SHA512withECDSA68*69* Note that the underlying PKCS#11 token may support complete signature70* algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just71* implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),72* or it may only implement the raw public key operation (CKM_RSA_X_509).73* This class uses what is available and adds whatever extra processing74* is needed.75*76* @author Andreas Sterbenz77* @since 1.578*/79final class P11Signature extends SignatureSpi {8081// token instance82private final Token token;8384// algorithm name85private final String algorithm;8687// name of the key algorithm, currently either RSA or DSA88private final String keyAlgorithm;8990// mechanism id91private final long mechanism;9293// digest algorithm OID, if we encode RSA signature ourselves94private final ObjectIdentifier digestOID;9596// type, one of T_* below97private final int type;9899// key instance used, if init*() was called100private P11Key p11Key;101102// message digest, if we do the digesting ourselves103private final MessageDigest md;104105// associated session, if any106private Session session;107108// mode, one of M_* below109private int mode;110111// flag indicating whether an operation is initialized112private boolean initialized;113114// buffer, for update(byte) or DSA115private final byte[] buffer;116117// total number of bytes processed in current operation118private int bytesProcessed;119120// constant for signing mode121private final static int M_SIGN = 1;122// constant for verification mode123private final static int M_VERIFY = 2;124125// constant for type digesting, we do the hashing ourselves126private final static int T_DIGEST = 1;127// constant for type update, token does everything128private final static int T_UPDATE = 2;129// constant for type raw, used with RawDSA and NONEwithECDSA only130private final static int T_RAW = 3;131132// XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",133// but this is a little arbitrary134private final static int RAW_ECDSA_MAX = 128;135136P11Signature(Token token, String algorithm, long mechanism)137throws NoSuchAlgorithmException, PKCS11Exception {138super();139this.token = token;140this.algorithm = algorithm;141this.mechanism = mechanism;142byte[] buffer = null;143ObjectIdentifier digestOID = null;144MessageDigest md = null;145switch ((int)mechanism) {146case (int)CKM_MD2_RSA_PKCS:147case (int)CKM_MD5_RSA_PKCS:148case (int)CKM_SHA1_RSA_PKCS:149case (int)CKM_SHA224_RSA_PKCS:150case (int)CKM_SHA256_RSA_PKCS:151case (int)CKM_SHA384_RSA_PKCS:152case (int)CKM_SHA512_RSA_PKCS:153keyAlgorithm = "RSA";154type = T_UPDATE;155buffer = new byte[1];156break;157case (int)CKM_DSA_SHA1:158keyAlgorithm = "DSA";159type = T_UPDATE;160buffer = new byte[1];161break;162case (int)CKM_ECDSA_SHA1:163keyAlgorithm = "EC";164type = T_UPDATE;165buffer = new byte[1];166break;167case (int)CKM_DSA:168keyAlgorithm = "DSA";169if (algorithm.equals("DSA")) {170type = T_DIGEST;171md = MessageDigest.getInstance("SHA-1");172} else if (algorithm.equals("RawDSA")) {173type = T_RAW;174buffer = new byte[20];175} else {176throw new ProviderException(algorithm);177}178break;179case (int)CKM_ECDSA:180keyAlgorithm = "EC";181if (algorithm.equals("NONEwithECDSA")) {182type = T_RAW;183buffer = new byte[RAW_ECDSA_MAX];184} else {185String digestAlg;186if (algorithm.equals("SHA1withECDSA")) {187digestAlg = "SHA-1";188} else if (algorithm.equals("SHA224withECDSA")) {189digestAlg = "SHA-224";190} else if (algorithm.equals("SHA256withECDSA")) {191digestAlg = "SHA-256";192} else if (algorithm.equals("SHA384withECDSA")) {193digestAlg = "SHA-384";194} else if (algorithm.equals("SHA512withECDSA")) {195digestAlg = "SHA-512";196} else {197throw new ProviderException(algorithm);198}199type = T_DIGEST;200md = MessageDigest.getInstance(digestAlg);201}202break;203case (int)CKM_RSA_PKCS:204case (int)CKM_RSA_X_509:205keyAlgorithm = "RSA";206type = T_DIGEST;207if (algorithm.equals("MD5withRSA")) {208md = MessageDigest.getInstance("MD5");209digestOID = AlgorithmId.MD5_oid;210} else if (algorithm.equals("SHA1withRSA")) {211md = MessageDigest.getInstance("SHA-1");212digestOID = AlgorithmId.SHA_oid;213} else if (algorithm.equals("MD2withRSA")) {214md = MessageDigest.getInstance("MD2");215digestOID = AlgorithmId.MD2_oid;216} else if (algorithm.equals("SHA224withRSA")) {217md = MessageDigest.getInstance("SHA-224");218digestOID = AlgorithmId.SHA224_oid;219} else if (algorithm.equals("SHA256withRSA")) {220md = MessageDigest.getInstance("SHA-256");221digestOID = AlgorithmId.SHA256_oid;222} else if (algorithm.equals("SHA384withRSA")) {223md = MessageDigest.getInstance("SHA-384");224digestOID = AlgorithmId.SHA384_oid;225} else if (algorithm.equals("SHA512withRSA")) {226md = MessageDigest.getInstance("SHA-512");227digestOID = AlgorithmId.SHA512_oid;228} else {229throw new ProviderException("Unknown signature: " + algorithm);230}231break;232default:233throw new ProviderException("Unknown mechanism: " + mechanism);234}235this.buffer = buffer;236this.digestOID = digestOID;237this.md = md;238}239240// reset the states to the pre-initialized values241private void reset(boolean doCancel) {242243if (!initialized) {244return;245}246initialized = false;247248try {249if (session == null) {250return;251}252253if (doCancel && token.explicitCancel) {254cancelOperation();255}256} finally {257p11Key.releaseKeyID();258session = token.releaseSession(session);259}260}261262private void cancelOperation() {263token.ensureValid();264// cancel operation by finishing it; avoid killSession as some265// hardware vendors may require re-login266try {267if (mode == M_SIGN) {268if (type == T_UPDATE) {269token.p11.C_SignFinal(session.id(), 0);270} else {271byte[] digest;272if (type == T_DIGEST) {273digest = md.digest();274} else { // T_RAW275digest = buffer;276}277token.p11.C_Sign(session.id(), digest);278}279} else { // M_VERIFY280byte[] signature;281if (keyAlgorithm.equals("DSA")) {282signature = new byte[40];283} else {284signature = new byte[(p11Key.length() + 7) >> 3];285}286if (type == T_UPDATE) {287token.p11.C_VerifyFinal(session.id(), signature);288} else {289byte[] digest;290if (type == T_DIGEST) {291digest = md.digest();292} else { // T_RAW293digest = buffer;294}295token.p11.C_Verify(session.id(), digest, signature);296}297}298} catch (PKCS11Exception e) {299if (e.getErrorCode() == CKR_OPERATION_NOT_INITIALIZED) {300// Cancel Operation may be invoked after an error on a PKCS#11301// call. If the operation inside the token was already cancelled,302// do not fail here. This is part of a defensive mechanism for303// PKCS#11 libraries that do not strictly follow the standard.304return;305}306if (mode == M_VERIFY) {307long errorCode = e.getErrorCode();308if ((errorCode == CKR_SIGNATURE_INVALID) ||309(errorCode == CKR_SIGNATURE_LEN_RANGE)) {310// expected since signature is incorrect311return;312}313}314throw new ProviderException("cancel failed", e);315}316}317318private void ensureInitialized() {319320if (!initialized) {321initialize();322}323}324325// assumes current state is initialized == false326private void initialize() {327328if (p11Key == null) {329throw new ProviderException(330"Operation cannot be performed without " +331"calling engineInit first");332}333long keyID = p11Key.getKeyID();334try {335token.ensureValid();336if (session == null) {337session = token.getOpSession();338}339if (mode == M_SIGN) {340token.p11.C_SignInit(session.id(),341new CK_MECHANISM(mechanism), keyID);342} else {343token.p11.C_VerifyInit(session.id(),344new CK_MECHANISM(mechanism), keyID);345}346} catch (PKCS11Exception e) {347p11Key.releaseKeyID();348session = token.releaseSession(session);349throw new ProviderException("Initialization failed", e);350}351if (bytesProcessed != 0) {352bytesProcessed = 0;353if (md != null) {354md.reset();355}356}357initialized = true;358}359360private void checkKeySize(String keyAlgo, Key key)361throws InvalidKeyException {362CK_MECHANISM_INFO mechInfo = null;363try {364mechInfo = token.getMechanismInfo(mechanism);365} catch (PKCS11Exception e) {366// should not happen, ignore for now.367}368if (mechInfo == null) {369// skip the check if no native info available370return;371}372int minKeySize = (int) mechInfo.ulMinKeySize;373int maxKeySize = (int) mechInfo.ulMaxKeySize;374// need to override the MAX keysize for SHA1withDSA375if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {376maxKeySize = 1024;377}378int keySize = 0;379if (key instanceof P11Key) {380keySize = ((P11Key) key).length();381} else {382try {383if (keyAlgo.equals("RSA")) {384keySize = ((RSAKey) key).getModulus().bitLength();385} else if (keyAlgo.equals("DSA")) {386keySize = ((DSAKey) key).getParams().getP().bitLength();387} else if (keyAlgo.equals("EC")) {388keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();389} else {390throw new ProviderException("Error: unsupported algo " + keyAlgo);391}392} catch (ClassCastException cce) {393throw new InvalidKeyException(keyAlgo +394" key must be the right type", cce);395}396}397if ((minKeySize != -1) && (keySize < minKeySize)) {398throw new InvalidKeyException(keyAlgo +399" key must be at least " + minKeySize + " bits");400}401if ((maxKeySize != -1) && (keySize > maxKeySize)) {402throw new InvalidKeyException(keyAlgo +403" key must be at most " + maxKeySize + " bits");404}405if (keyAlgo.equals("RSA")) {406checkRSAKeyLength(keySize);407}408}409410private void checkRSAKeyLength(int len) throws InvalidKeyException {411RSAPadding padding;412try {413padding = RSAPadding.getInstance414(RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);415} catch (InvalidAlgorithmParameterException iape) {416throw new InvalidKeyException(iape.getMessage());417}418int maxDataSize = padding.getMaxDataSize();419int encodedLength;420if (algorithm.equals("MD5withRSA") ||421algorithm.equals("MD2withRSA")) {422encodedLength = 34;423} else if (algorithm.equals("SHA1withRSA")) {424encodedLength = 35;425} else if (algorithm.equals("SHA224withRSA")) {426encodedLength = 47;427} else if (algorithm.equals("SHA256withRSA")) {428encodedLength = 51;429} else if (algorithm.equals("SHA384withRSA")) {430encodedLength = 67;431} else if (algorithm.equals("SHA512withRSA")) {432encodedLength = 83;433} else {434throw new ProviderException("Unknown signature algo: " + algorithm);435}436if (encodedLength > maxDataSize) {437throw new InvalidKeyException438("Key is too short for this signature algorithm");439}440}441442// see JCA spec443@Override444protected void engineInitVerify(PublicKey publicKey)445throws InvalidKeyException {446if (publicKey == null) {447throw new InvalidKeyException("Key must not be null");448}449// Need to check key length whenever a new key is set450if (publicKey != p11Key) {451checkKeySize(keyAlgorithm, publicKey);452}453reset(true);454mode = M_VERIFY;455p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);456initialize();457}458459// see JCA spec460@Override461protected void engineInitSign(PrivateKey privateKey)462throws InvalidKeyException {463if (privateKey == null) {464throw new InvalidKeyException("Key must not be null");465}466// Need to check RSA key length whenever a new key is set467if (privateKey != p11Key) {468checkKeySize(keyAlgorithm, privateKey);469}470reset(true);471mode = M_SIGN;472p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);473initialize();474}475476// see JCA spec477@Override478protected void engineUpdate(byte b) throws SignatureException {479ensureInitialized();480switch (type) {481case T_UPDATE:482buffer[0] = b;483engineUpdate(buffer, 0, 1);484break;485case T_DIGEST:486md.update(b);487bytesProcessed++;488break;489case T_RAW:490if (bytesProcessed >= buffer.length) {491bytesProcessed = buffer.length + 1;492return;493}494buffer[bytesProcessed++] = b;495break;496default:497throw new ProviderException("Internal error");498}499}500501// see JCA spec502@Override503protected void engineUpdate(byte[] b, int ofs, int len)504throws SignatureException {505506ensureInitialized();507if (len == 0) {508return;509}510// check for overflow511if (len + bytesProcessed < 0) {512throw new ProviderException("Processed bytes limits exceeded.");513}514switch (type) {515case T_UPDATE:516try {517if (mode == M_SIGN) {518token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);519} else {520token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);521}522bytesProcessed += len;523} catch (PKCS11Exception e) {524reset(false);525throw new ProviderException(e);526}527break;528case T_DIGEST:529md.update(b, ofs, len);530bytesProcessed += len;531break;532case T_RAW:533if (bytesProcessed + len > buffer.length) {534bytesProcessed = buffer.length + 1;535return;536}537System.arraycopy(b, ofs, buffer, bytesProcessed, len);538bytesProcessed += len;539break;540default:541throw new ProviderException("Internal error");542}543}544545// see JCA spec546@Override547protected void engineUpdate(ByteBuffer byteBuffer) {548549ensureInitialized();550int len = byteBuffer.remaining();551if (len <= 0) {552return;553}554switch (type) {555case T_UPDATE:556if (byteBuffer instanceof DirectBuffer == false) {557// cannot do better than default impl558super.engineUpdate(byteBuffer);559return;560}561long addr = ((DirectBuffer)byteBuffer).address();562int ofs = byteBuffer.position();563try {564if (mode == M_SIGN) {565token.p11.C_SignUpdate566(session.id(), addr + ofs, null, 0, len);567} else {568token.p11.C_VerifyUpdate569(session.id(), addr + ofs, null, 0, len);570}571bytesProcessed += len;572byteBuffer.position(ofs + len);573} catch (PKCS11Exception e) {574reset(false);575throw new ProviderException("Update failed", e);576}577break;578case T_DIGEST:579md.update(byteBuffer);580bytesProcessed += len;581break;582case T_RAW:583if (bytesProcessed + len > buffer.length) {584bytesProcessed = buffer.length + 1;585return;586}587byteBuffer.get(buffer, bytesProcessed, len);588bytesProcessed += len;589break;590default:591reset(false);592throw new ProviderException("Internal error");593}594}595596// see JCA spec597@Override598protected byte[] engineSign() throws SignatureException {599600ensureInitialized();601boolean doCancel = true;602try {603byte[] signature;604if (type == T_UPDATE) {605int len = keyAlgorithm.equals("DSA") ? 40 : 0;606signature = token.p11.C_SignFinal(session.id(), len);607} else {608byte[] digest;609if (type == T_DIGEST) {610digest = md.digest();611} else { // T_RAW612if (mechanism == CKM_DSA) {613if (bytesProcessed != buffer.length) {614throw new SignatureException615("Data for RawDSA must be exactly 20 bytes long");616}617digest = buffer;618} else { // CKM_ECDSA619if (bytesProcessed > buffer.length) {620throw new SignatureException("Data for NONEwithECDSA"621+ " must be at most " + RAW_ECDSA_MAX + " bytes long");622}623digest = new byte[bytesProcessed];624System.arraycopy(buffer, 0, digest, 0, bytesProcessed);625}626}627if (keyAlgorithm.equals("RSA") == false) {628// DSA and ECDSA629signature = token.p11.C_Sign(session.id(), digest);630} else { // RSA631byte[] data = encodeSignature(digest);632if (mechanism == CKM_RSA_X_509) {633data = pkcs1Pad(data);634}635signature = token.p11.C_Sign(session.id(), data);636}637}638doCancel = false;639640if (keyAlgorithm.equals("RSA") == false) {641return dsaToASN1(signature);642} else {643return signature;644}645} catch (PKCS11Exception e) {646// As per the PKCS#11 standard, C_Sign and C_SignFinal may only647// keep the operation active on CKR_BUFFER_TOO_SMALL errors or648// successful calls to determine the output length. However,649// these cases are handled at OpenJDK's libj2pkcs11 native650// library. Thus, doCancel can safely be 'false' here.651doCancel = false;652throw new ProviderException(e);653} finally {654reset(doCancel);655}656}657658// see JCA spec659@Override660protected boolean engineVerify(byte[] signature) throws SignatureException {661ensureInitialized();662boolean doCancel = true;663try {664if (keyAlgorithm.equals("DSA")) {665signature = asn1ToDSA(signature);666} else if (keyAlgorithm.equals("EC")) {667signature = asn1ToECDSA(signature);668}669if (type == T_UPDATE) {670token.p11.C_VerifyFinal(session.id(), signature);671} else {672byte[] digest;673if (type == T_DIGEST) {674digest = md.digest();675} else { // T_RAW676if (mechanism == CKM_DSA) {677if (bytesProcessed != buffer.length) {678throw new SignatureException679("Data for RawDSA must be exactly 20 bytes long");680}681digest = buffer;682} else {683if (bytesProcessed > buffer.length) {684throw new SignatureException("Data for NONEwithECDSA"685+ " must be at most " + RAW_ECDSA_MAX + " bytes long");686}687digest = new byte[bytesProcessed];688System.arraycopy(buffer, 0, digest, 0, bytesProcessed);689}690}691if (keyAlgorithm.equals("RSA") == false) {692// DSA and ECDSA693token.p11.C_Verify(session.id(), digest, signature);694} else { // RSA695byte[] data = encodeSignature(digest);696if (mechanism == CKM_RSA_X_509) {697data = pkcs1Pad(data);698}699token.p11.C_Verify(session.id(), data, signature);700}701}702doCancel = false;703return true;704} catch (PKCS11Exception e) {705doCancel = false;706long errorCode = e.getErrorCode();707if (errorCode == CKR_SIGNATURE_INVALID) {708return false;709}710if (errorCode == CKR_SIGNATURE_LEN_RANGE) {711// return false rather than throwing an exception712return false;713}714// ECF bug?715if (errorCode == CKR_DATA_LEN_RANGE) {716return false;717}718throw new ProviderException(e);719} finally {720reset(doCancel);721}722}723724private byte[] pkcs1Pad(byte[] data) {725try {726int len = (p11Key.length() + 7) >> 3;727RSAPadding padding = RSAPadding.getInstance728(RSAPadding.PAD_BLOCKTYPE_1, len);729byte[] padded = padding.pad(data);730return padded;731} catch (GeneralSecurityException e) {732throw new ProviderException(e);733}734}735736private byte[] encodeSignature(byte[] digest) throws SignatureException {737try {738return RSASignature.encodeSignature(digestOID, digest);739} catch (IOException e) {740throw new SignatureException("Invalid encoding", e);741}742}743744// private static byte[] decodeSignature(byte[] signature) throws IOException {745// return RSASignature.decodeSignature(digestOID, signature);746// }747748// For DSA and ECDSA signatures, PKCS#11 represents them as a simple749// byte array that contains the concatenation of r and s.750// For DSA, r and s are always exactly 20 bytes long.751// For ECDSA, r and s are of variable length, but we know that each752// occupies half of the array.753private static byte[] dsaToASN1(byte[] signature) {754int n = signature.length >> 1;755BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));756BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));757try {758DerOutputStream outseq = new DerOutputStream(100);759outseq.putInteger(r);760outseq.putInteger(s);761DerValue result = new DerValue(DerValue.tag_Sequence,762outseq.toByteArray());763return result.toByteArray();764} catch (java.io.IOException e) {765throw new RuntimeException("Internal error", e);766}767}768769private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {770try {771// Enforce strict DER checking for signatures772DerInputStream in = new DerInputStream(sig, 0, sig.length, false);773DerValue[] values = in.getSequence(2);774775// check number of components in the read sequence776// and trailing data777if ((values.length != 2) || (in.available() != 0)) {778throw new IOException("Invalid encoding for signature");779}780781BigInteger r = values[0].getPositiveBigInteger();782BigInteger s = values[1].getPositiveBigInteger();783784byte[] br = toByteArray(r, 20);785byte[] bs = toByteArray(s, 20);786if ((br == null) || (bs == null)) {787throw new SignatureException("Out of range value for R or S");788}789return P11Util.concat(br, bs);790} catch (SignatureException e) {791throw e;792} catch (Exception e) {793throw new SignatureException("Invalid encoding for signature", e);794}795}796797private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {798try {799// Enforce strict DER checking for signatures800DerInputStream in = new DerInputStream(sig, 0, sig.length, false);801DerValue[] values = in.getSequence(2);802803// check number of components in the read sequence804// and trailing data805if ((values.length != 2) || (in.available() != 0)) {806throw new IOException("Invalid encoding for signature");807}808809BigInteger r = values[0].getPositiveBigInteger();810BigInteger s = values[1].getPositiveBigInteger();811812// trim leading zeroes813byte[] br = KeyUtil.trimZeroes(r.toByteArray());814byte[] bs = KeyUtil.trimZeroes(s.toByteArray());815int k = Math.max(br.length, bs.length);816// r and s each occupy half the array817byte[] res = new byte[k << 1];818System.arraycopy(br, 0, res, k - br.length, br.length);819System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);820return res;821} catch (Exception e) {822throw new SignatureException("Invalid encoding for signature", e);823}824}825826private static byte[] toByteArray(BigInteger bi, int len) {827byte[] b = bi.toByteArray();828int n = b.length;829if (n == len) {830return b;831}832if ((n == len + 1) && (b[0] == 0)) {833byte[] t = new byte[len];834System.arraycopy(b, 1, t, 0, len);835return t;836}837if (n > len) {838return null;839}840// must be smaller841byte[] t = new byte[len];842System.arraycopy(b, 0, t, (len - n), n);843return t;844}845846// see JCA spec847@Override848protected void engineSetParameter(String param, Object value)849throws InvalidParameterException {850throw new UnsupportedOperationException("setParameter() not supported");851}852853// see JCA spec854@Override855protected void engineSetParameter(AlgorithmParameterSpec params)856throws InvalidAlgorithmParameterException {857if (params != null) {858throw new InvalidAlgorithmParameterException("No parameter accepted");859}860}861862// see JCA spec863@Override864protected Object engineGetParameter(String param)865throws InvalidParameterException {866throw new UnsupportedOperationException("getParameter() not supported");867}868869// see JCA spec870@Override871protected AlgorithmParameters engineGetParameters() {872return null;873}874}875876877