1 package org.bouncycastle.jcajce.provider.symmetric;
2 
3 import java.security.AlgorithmParameters;
4 import java.security.InvalidAlgorithmParameterException;
5 import java.security.SecureRandom;
6 import java.security.spec.AlgorithmParameterSpec;
7 
8 import javax.crypto.spec.IvParameterSpec;
9 
10 import org.bouncycastle.crypto.BlockCipher;
11 import org.bouncycastle.crypto.CipherKeyGenerator;
12 import org.bouncycastle.crypto.CryptoServicesRegistrar;
13 import org.bouncycastle.crypto.engines.SM4Engine;
14 import org.bouncycastle.crypto.generators.Poly1305KeyGenerator;
15 import org.bouncycastle.crypto.macs.CMac;
16 import org.bouncycastle.crypto.macs.GMac;
17 import org.bouncycastle.crypto.modes.GCMBlockCipher;
18 import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
19 import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameterGenerator;
20 import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
21 import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
22 import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
23 import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider;
24 import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
25 
26 public final class SM4
27 {
SM4()28     private SM4()
29     {
30     }
31 
32     public static class ECB
33         extends BaseBlockCipher
34     {
ECB()35         public ECB()
36         {
37             super(new BlockCipherProvider()
38             {
39                 public BlockCipher get()
40                 {
41                     return new SM4Engine();
42                 }
43             });
44         }
45     }
46 
47     public static class KeyGen
48         extends BaseKeyGenerator
49     {
KeyGen()50         public KeyGen()
51         {
52             super("SM4", 128, new CipherKeyGenerator());
53         }
54     }
55 
56     public static class CMAC
57         extends BaseMac
58     {
CMAC()59         public CMAC()
60         {
61             super(new CMac(new SM4Engine()));
62         }
63     }
64 
65     public static class GMAC
66         extends BaseMac
67     {
GMAC()68         public GMAC()
69         {
70             super(new GMac(new GCMBlockCipher(new SM4Engine())));
71         }
72     }
73 
74     public static class Poly1305
75         extends BaseMac
76     {
Poly1305()77         public Poly1305()
78         {
79             super(new org.bouncycastle.crypto.macs.Poly1305(new SM4Engine()));
80         }
81     }
82 
83     public static class Poly1305KeyGen
84         extends BaseKeyGenerator
85     {
Poly1305KeyGen()86         public Poly1305KeyGen()
87         {
88             super("Poly1305-SM4", 256, new Poly1305KeyGenerator());
89         }
90     }
91 
92     public static class AlgParamGen
93         extends BaseAlgorithmParameterGenerator
94     {
engineInit( AlgorithmParameterSpec genParamSpec, SecureRandom random)95         protected void engineInit(
96             AlgorithmParameterSpec genParamSpec,
97             SecureRandom random)
98             throws InvalidAlgorithmParameterException
99         {
100             throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for SM4 parameter generation.");
101         }
102 
engineGenerateParameters()103         protected AlgorithmParameters engineGenerateParameters()
104         {
105             byte[] iv = new byte[16];
106 
107             if (random == null)
108             {
109                 random = CryptoServicesRegistrar.getSecureRandom();
110             }
111 
112             random.nextBytes(iv);
113 
114             AlgorithmParameters params;
115 
116             try
117             {
118                 params = createParametersInstance("SM4");
119                 params.init(new IvParameterSpec(iv));
120             }
121             catch (Exception e)
122             {
123                 throw new RuntimeException(e.getMessage());
124             }
125 
126             return params;
127         }
128     }
129 
130     public static class AlgParams
131         extends IvAlgorithmParameters
132     {
engineToString()133         protected String engineToString()
134         {
135             return "SM4 IV";
136         }
137     }
138 
139     public static class Mappings
140         extends SymmetricAlgorithmProvider
141     {
142         private static final String PREFIX = SM4.class.getName();
143 
Mappings()144         public Mappings()
145         {
146         }
147 
configure(ConfigurableProvider provider)148         public void configure(ConfigurableProvider provider)
149         {
150             provider.addAlgorithm("AlgorithmParameters.SM4", PREFIX + "$AlgParams");
151 
152             provider.addAlgorithm("AlgorithmParameterGenerator.SM4", PREFIX + "$AlgParamGen");
153 
154             provider.addAlgorithm("Cipher.SM4", PREFIX + "$ECB");
155 
156             provider.addAlgorithm("KeyGenerator.SM4", PREFIX + "$KeyGen");
157 
158             addCMacAlgorithm(provider, "SM4", PREFIX + "$CMAC", PREFIX + "$KeyGen");
159             addGMacAlgorithm(provider, "SM4", PREFIX + "$GMAC", PREFIX + "$KeyGen");
160             addPoly1305Algorithm(provider, "SM4", PREFIX + "$Poly1305", PREFIX + "$Poly1305KeyGen");
161         }
162     }
163 }
164