SmartPGP/src/dev/c0de/smartpgp/Common.java

177 lines
5.7 KiB
Java

/*
SmartPGP : JavaCard implementation of OpenPGP card v3 specification
https://c0de.dev/c0de/SmartPGP
Copyright (C) 2016 ANSSI
Copyright (C) 2023 Code Fox <SmartPGP@c0de.dev>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package dev.c0de.smartpgp;
import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;
public final class Common {
protected final Cipher cipher_aes_cbc_nopad;
protected final Cipher cipher_rsa_pkcs1;
protected final RandomData random;
protected Common() {
cipher_aes_cbc_nopad = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
cipher_rsa_pkcs1 = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);
random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
}
protected static final void beginTransaction(final boolean isRegistering) {
if(!isRegistering) {
JCSystem.beginTransaction();
}
}
protected static final void commitTransaction(final boolean isRegistering) {
if(!isRegistering) {
JCSystem.commitTransaction();
}
}
protected static final short writeLength(final byte[] buf, short off, final short len) {
if(len > 0xff) {
buf[off] = (byte)0x82;
return Util.setShort(buf, (short)(off+1), len);
}
if(len > 0x7f) {
buf[off++] = (byte)0x81;
buf[off++] = (byte)(len & 0xff);
return off;
}
buf[off++] = (byte)(len & 0x7f);
return off;
}
protected static final short skipLength(final byte[] buf, final short off, final short len) {
if(len < 1) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return off;
}
if((buf[off] & (byte)0x80) == 0) {
return (short)(off + 1);
}
switch(buf[off]) {
case (byte)0x81:
if(len < 2) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return off;
}
return (short)(off + 2);
case (byte)0x82:
if(len < 3) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return off;
}
return (short)(off + 3);
default:
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return off;
}
}
protected static final short readLength(final byte[] buf, final short off, final short len) {
if(len < 1) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return (short)0;
}
if((buf[off] & (byte)0x80) == 0) {
return Util.makeShort((byte)0, buf[off]);
}
switch(buf[off]) {
case (byte)0x81:
if(len < 2) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return (short)0;
}
return Util.makeShort((byte)0, buf[(short)(off + 1)]);
case (byte)0x82:
if(len < 3) {
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return (short)0;
}
return Util.getShort(buf, (short)(off + 1));
default:
ISOException.throwIt(ISO7816.SW_WRONG_DATA);
return (short)0;
}
}
protected static final short bitsToBytes(final short bits) {
return (short)((bits / 8) + (short)(((bits % 8) == 0) ? 0 : 1));
}
protected static final void arrayLeftShift(final byte[] inBuf, short inOff,
final byte[] outBuf, short outOff,
final short len) {
if(len > 0) {
outBuf[outOff++] = (byte)(inBuf[inOff++] << 1);
for(short i = 1; i < len; ++i) {
if((inBuf[inOff] & (byte)0x80) != (byte)0) {
outBuf[(short)(outOff - 1)] |= (byte)0x01;
}
outBuf[outOff++] = (byte)(inBuf[inOff++] << 1);
}
}
}
protected static final void arrayXor(final byte[] inBuf1, short inOff1,
final byte[] inBuf2, short inOff2,
final byte[] outBuf, short outOff,
final short len) {
for(short i = 0; i < len; ++i) {
outBuf[outOff++] = (byte)(inBuf1[inOff1++] ^ inBuf2[inOff2++]);
}
}
protected static final short writeAlgorithmInformation(final byte key_tag,
final byte[] buf, short off) {
for(short m = 2; m <= 4; ++m) {
for(byte form = Constants.RSA_IMPORT_SUPPORTS_FORMAT_1 ? 1 : 3; form <= 3; form += 2) {
buf[off++] = key_tag;
buf[off++] = (byte)6; /* len */
buf[off++] = (byte)0x01; /* RSA */
off = Util.setShort(buf, off, (short)(m * 1024)); /* modulus bit size */
off = Util.setShort(buf, off, (short)0x11); /* 65537 = 17 bits public exponent size */
buf[off++] = form;
}
}
return off;
}
}