Skip to content

Commit

Permalink
TKSS-927: Refactor NativeSM2
Browse files Browse the repository at this point in the history
  • Loading branch information
johnshajiang committed Nov 19, 2024
1 parent 2e166ea commit 401b271
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 260 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,12 @@ private static void copyNativeLib(String libName, Path libPath)
native byte[] sm2ToUncompPubKey(byte[] compPubKey);
native byte[] sm2GenPubKey(byte[] priKey);

native long sm2CreateCtx();
native long sm2CreateCtxWithKey(byte[] key);
native void sm2FreeCtx(long pointer);

native byte[] sm2GenKeyPair(long pointer);

native byte[] sm2Encrypt(long pointer, byte[] plaintext);
native byte[] sm2Decrypt(long pointer, byte[] ciphertext);
native long sm2KeyGenCreateCtx();
native void sm2KeyGenFreeCtx(long pointer);
native byte[] sm2KeyGenGenKeyPair(long pointer);

native long sm2CipherCreateCtx(byte[] key);
native void sm2CipherFreeCtx(long pointer);
native byte[] sm2CipherEncrypt(long pointer, byte[] plaintext);
native byte[] sm2CipherDecrypt(long pointer, byte[] ciphertext);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2024, THL A29 Limited, a Tencent company. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. THL A29 Limited designates
* this particular file as subject to the "Classpath" exception as provided
* in the LICENSE file that accompanied this code.
*
* This code 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 version 2 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 com.tencent.kona.crypto.provider.nativeImpl;

import javax.crypto.BadPaddingException;

import static com.tencent.kona.crypto.provider.nativeImpl.NativeCrypto.nativeCrypto;
import static com.tencent.kona.crypto.util.Constants.*;

/**
* The SM2 cipher native implementation.
*/
final class NativeSM2Cipher extends NativeRef {

// key can be private key, public key or even key pair.
NativeSM2Cipher(byte[] key) {
super(createCtx(key));
}

private static long createCtx(byte[] key) {
checkKey(key);

return nativeCrypto().sm2CipherCreateCtx(key);
}

private static void checkKey(byte[] key) {
if (key == null || (
key.length != SM2_PRIKEY_LEN &&
key.length != SM2_PUBKEY_LEN &&
key.length != (SM2_PRIKEY_LEN + SM2_PUBKEY_LEN))) {
throw new IllegalStateException("Illegal key");
}
}

public byte[] encrypt(byte[] plaintext) throws BadPaddingException {
if (!checkInputBound(plaintext, 0, plaintext.length)) {
throw new BadPaddingException("Invalid plaintext");
}

byte[] ciphertext = nativeCrypto().sm2CipherEncrypt(pointer, plaintext);
if (ciphertext == null) {
throw new BadPaddingException("Encrypt failed");
}
return ciphertext;
}

public byte[] decrypt(byte[] ciphertext) throws BadPaddingException {
if (!checkInputBound(ciphertext, 0, ciphertext.length)) {
throw new BadPaddingException("Invalid ciphertext");
}

byte[] cleartext = nativeCrypto().sm2CipherDecrypt(pointer, ciphertext);
if (cleartext == null) {
throw new BadPaddingException("Decrypt failed");
}
return cleartext;
}

@Override
public void close() {
nativeCrypto().sm2CipherFreeCtx(pointer);
super.close();
}

private static boolean checkInputBound(byte[] input, int offset, int len) {
return input != null
&& offset >= 0 && len > 0
&& (input.length >= (offset + len));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,28 @@

import com.tencent.kona.crypto.CryptoUtils;

import javax.crypto.BadPaddingException;

import static com.tencent.kona.crypto.provider.nativeImpl.NativeCrypto.nativeCrypto;

import static com.tencent.kona.crypto.util.Constants.*;

/**
* The SM2 native implementation.
* The SM2 key generation native implementation.
*/
final class NativeSM2 extends NativeRef {
final class NativeSM2KeyGen extends NativeRef {

NativeSM2() {
NativeSM2KeyGen() {
super(createCtx());
}

private static long createCtx() {
return nativeCrypto().sm2CreateCtx();
}

// key can be private key, public key or even key pair.
NativeSM2(byte[] key) {
super(createCtx(key));
}

private static long createCtx(byte[] key) {
if (key == null || (
key.length != SM2_PRIKEY_LEN &&
key.length != SM2_PUBKEY_LEN &&
key.length != (SM2_PRIKEY_LEN + SM2_PUBKEY_LEN))) {
throw new IllegalStateException("Illegal key");
}

return nativeCrypto().sm2CreateCtxWithKey(key);
return nativeCrypto().sm2KeyGenCreateCtx();
}

// Format: K || 0x04 || X || Y, 97-bytes
// K is the private key, 32-bytes
// X and Y are the coordinates of the public key, 32-bytes
public byte[] genKeyPair() {
byte[] keyPair = nativeCrypto().sm2GenKeyPair(pointer);
byte[] keyPair = nativeCrypto().sm2KeyGenGenKeyPair(pointer);

if (keyPair.length == SM2_PRIKEY_LEN + SM2_PUBKEY_LEN) {
return keyPair;
Expand All @@ -78,33 +60,9 @@ public byte[] genKeyPair() {
throw new IllegalStateException("Illegal key pair");
}

public byte[] encrypt(byte[] plaintext) throws BadPaddingException {
if (!checkInputBound(plaintext, 0, plaintext.length)) {
throw new BadPaddingException("Invalid input");
}

byte[] ciphertext = nativeCrypto().sm2Encrypt(pointer, plaintext);
if (ciphertext == null) {
throw new BadPaddingException("Encrypt failed");
}
return ciphertext;
}

public byte[] decrypt(byte[] ciphertext) throws BadPaddingException {
if (!checkInputBound(ciphertext, 0, ciphertext.length)) {
throw new BadPaddingException("Invalid input");
}

byte[] cleartext = nativeCrypto().sm2Decrypt(pointer, ciphertext);
if (cleartext == null) {
throw new BadPaddingException("Decrypt failed");
}
return cleartext;
}

@Override
public void close() {
nativeCrypto().sm2FreeCtx(pointer);
nativeCrypto().sm2KeyGenFreeCtx(pointer);
super.close();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public final class SM2Cipher extends CipherSpi {

private static final byte[] B0 = new byte[0];

private NativeSM2 sm2;
private NativeSM2Cipher sm2;
private final Buffer buffer = new Buffer();

private boolean encrypted = true;
Expand Down Expand Up @@ -81,7 +81,7 @@ public void engineInit(int opmode, Key key, SecureRandom random)

if (key instanceof ECPublicKey) {
SM2PublicKey publicKey = new SM2PublicKey((ECPublicKey) key);
sm2 = new NativeSM2(publicKey.getEncoded());
sm2 = new NativeSM2Cipher(publicKey.getEncoded());
} else {
throw new InvalidKeyException(
"Only accept ECPublicKey for encryption");
Expand All @@ -98,7 +98,7 @@ public void engineInit(int opmode, Key key, SecureRandom random)
"within the range [1, n - 1]");
}

sm2 = new NativeSM2(privateKey.getEncoded());
sm2 = new NativeSM2Cipher(privateKey.getEncoded());
} else {
throw new InvalidKeyException(
"Only accept ECPrivateKey for decryption");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ public final class SM2KeyPairGenerator extends KeyPairGenerator {

private static final Sweeper SWEEPER = Sweeper.instance();

private final NativeSM2 sm2;
private final NativeSM2KeyGen sm2;

public SM2KeyPairGenerator() {
super("SM2");
sm2 = new NativeSM2();
sm2 = new NativeSM2KeyGen();

SWEEPER.register(this, new SweepNativeRef(sm2));
}
Expand Down
Loading

0 comments on commit 401b271

Please sign in to comment.