aboutsummaryrefslogtreecommitdiffstats
path: root/SoftHSMv2/src/lib/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'SoftHSMv2/src/lib/crypto')
-rw-r--r--SoftHSMv2/src/lib/crypto/AESKey.cpp67
-rw-r--r--SoftHSMv2/src/lib/crypto/AESKey.h51
-rw-r--r--SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.cpp221
-rw-r--r--SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h184
-rw-r--r--SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.cpp41
-rw-r--r--SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.h66
-rw-r--r--SoftHSMv2/src/lib/crypto/AsymmetricParameters.h59
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanAES.cpp354
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanAES.h60
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp308
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanCryptoFactory.h105
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDES.cpp153
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDES.h63
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDH.cpp408
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDH.h80
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDHKeyPair.cpp70
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDHKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.cpp310
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.h117
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDHPublicKey.cpp146
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDHPublicKey.h77
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSA.cpp760
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSA.h86
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.cpp70
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.cpp243
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.h86
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.cpp162
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.h78
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDH.cpp356
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDH.h79
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.cpp71
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.cpp259
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.h87
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.cpp151
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.h79
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSA.cpp465
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSA.h84
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.cpp71
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.cpp255
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.h87
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.cpp151
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.h79
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOST.cpp535
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOST.h82
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.cpp71
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp201
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.h94
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.cpp201
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.h86
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTR3411.cpp47
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanGOSTR3411.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.cpp133
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.h64
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanMAC.cpp154
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanMAC.h107
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanMD5.cpp45
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanMD5.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.cpp310
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.h74
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRNG.cpp87
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRNG.h66
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSA.cpp1219
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSA.h90
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.cpp70
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.cpp304
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.h89
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.cpp131
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.h75
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA1.cpp45
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA1.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA224.cpp45
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA224.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA256.cpp45
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA256.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA384.cpp45
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA384.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA512.cpp45
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSHA512.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.cpp593
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.h83
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanUtil.cpp146
-rw-r--r--SoftHSMv2/src/lib/crypto/BotanUtil.h68
-rw-r--r--SoftHSMv2/src/lib/crypto/Botan_ecb.cpp153
-rw-r--r--SoftHSMv2/src/lib/crypto/Botan_ecb.h107
-rw-r--r--SoftHSMv2/src/lib/crypto/Botan_rounding.h68
-rw-r--r--SoftHSMv2/src/lib/crypto/CryptoFactory.cpp102
-rw-r--r--SoftHSMv2/src/lib/crypto/CryptoFactory.h97
-rw-r--r--SoftHSMv2/src/lib/crypto/DESKey.cpp115
-rw-r--r--SoftHSMv2/src/lib/crypto/DESKey.h55
-rw-r--r--SoftHSMv2/src/lib/crypto/DHParameters.cpp111
-rw-r--r--SoftHSMv2/src/lib/crypto/DHParameters.h81
-rw-r--r--SoftHSMv2/src/lib/crypto/DHPrivateKey.cpp120
-rw-r--r--SoftHSMv2/src/lib/crypto/DHPrivateKey.h81
-rw-r--r--SoftHSMv2/src/lib/crypto/DHPublicKey.cpp118
-rw-r--r--SoftHSMv2/src/lib/crypto/DHPublicKey.h74
-rw-r--r--SoftHSMv2/src/lib/crypto/DSAParameters.cpp108
-rw-r--r--SoftHSMv2/src/lib/crypto/DSAParameters.h78
-rw-r--r--SoftHSMv2/src/lib/crypto/DSAPrivateKey.cpp134
-rw-r--r--SoftHSMv2/src/lib/crypto/DSAPrivateKey.h83
-rw-r--r--SoftHSMv2/src/lib/crypto/DSAPublicKey.cpp132
-rw-r--r--SoftHSMv2/src/lib/crypto/DSAPublicKey.h76
-rw-r--r--SoftHSMv2/src/lib/crypto/ECParameters.cpp78
-rw-r--r--SoftHSMv2/src/lib/crypto/ECParameters.h64
-rw-r--r--SoftHSMv2/src/lib/crypto/ECPrivateKey.cpp106
-rw-r--r--SoftHSMv2/src/lib/crypto/ECPrivateKey.h82
-rw-r--r--SoftHSMv2/src/lib/crypto/ECPublicKey.cpp104
-rw-r--r--SoftHSMv2/src/lib/crypto/ECPublicKey.h75
-rw-r--r--SoftHSMv2/src/lib/crypto/GOSTPrivateKey.cpp75
-rw-r--r--SoftHSMv2/src/lib/crypto/GOSTPrivateKey.h79
-rw-r--r--SoftHSMv2/src/lib/crypto/GOSTPublicKey.cpp75
-rw-r--r--SoftHSMv2/src/lib/crypto/GOSTPublicKey.h72
-rw-r--r--SoftHSMv2/src/lib/crypto/HashAlgorithm.cpp76
-rw-r--r--SoftHSMv2/src/lib/crypto/HashAlgorithm.h80
-rw-r--r--SoftHSMv2/src/lib/crypto/MacAlgorithm.cpp128
-rw-r--r--SoftHSMv2/src/lib/crypto/MacAlgorithm.h101
-rw-r--r--SoftHSMv2/src/lib/crypto/Makefile.am126
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLAES.cpp275
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLAES.h64
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLCMAC.cpp84
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLCMAC.h55
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLComp.cpp415
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLComp.h98
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp388
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h116
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDES.cpp165
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDES.h64
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDH.cpp430
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDH.h80
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.cpp70
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.cpp239
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.h85
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.cpp175
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.h77
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSA.cpp695
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSA.h86
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.cpp70
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.cpp256
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.h86
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.cpp193
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.h78
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECDH.cpp375
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECDH.h79
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECDSA.cpp457
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECDSA.h80
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECKeyPair.cpp71
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.cpp187
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.h85
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECPublicKey.cpp131
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLECPublicKey.h76
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.cpp244
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.h77
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.cpp133
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.h66
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.cpp220
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.h77
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.cpp575
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.h81
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOST.cpp658
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOST.h85
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.cpp71
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.cpp184
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.h88
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.cpp162
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.h80
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.cpp48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLHMAC.cpp109
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLHMAC.h92
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLMD5.cpp46
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLMD5.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRNG.cpp52
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRNG.h53
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSA.cpp1554
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSA.h87
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.cpp70
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.cpp320
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.h90
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.cpp155
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.h76
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA1.cpp46
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA1.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA224.cpp46
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA224.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA256.cpp46
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA256.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA384.cpp46
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA384.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA512.cpp46
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLSHA512.h48
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLUtil.cpp199
-rw-r--r--SoftHSMv2/src/lib/crypto/OSSLUtil.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/PrivateKey.h72
-rw-r--r--SoftHSMv2/src/lib/crypto/PublicKey.h65
-rw-r--r--SoftHSMv2/src/lib/crypto/RNG.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/RSAParameters.cpp94
-rw-r--r--SoftHSMv2/src/lib/crypto/RSAParameters.h74
-rw-r--r--SoftHSMv2/src/lib/crypto/RSAPrivateKey.cpp186
-rw-r--r--SoftHSMv2/src/lib/crypto/RSAPrivateKey.h91
-rw-r--r--SoftHSMv2/src/lib/crypto/RSAPublicKey.cpp105
-rw-r--r--SoftHSMv2/src/lib/crypto/RSAPublicKey.h72
-rw-r--r--SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.cpp229
-rw-r--r--SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.h148
-rw-r--r--SoftHSMv2/src/lib/crypto/SymmetricKey.cpp109
-rw-r--r--SoftHSMv2/src/lib/crypto/SymmetricKey.h78
-rw-r--r--SoftHSMv2/src/lib/crypto/odd.h72
-rw-r--r--SoftHSMv2/src/lib/crypto/test/AESTests.cpp1182
-rw-r--r--SoftHSMv2/src/lib/crypto/test/AESTests.h78
-rw-r--r--SoftHSMv2/src/lib/crypto/test/DESTests.cpp1164
-rw-r--r--SoftHSMv2/src/lib/crypto/test/DESTests.h65
-rw-r--r--SoftHSMv2/src/lib/crypto/test/DHTests.cpp245
-rw-r--r--SoftHSMv2/src/lib/crypto/test/DHTests.h65
-rw-r--r--SoftHSMv2/src/lib/crypto/test/DSATests.cpp338
-rw-r--r--SoftHSMv2/src/lib/crypto/test/DSATests.h65
-rw-r--r--SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp268
-rw-r--r--SoftHSMv2/src/lib/crypto/test/ECDHTests.h65
-rw-r--r--SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp301
-rw-r--r--SoftHSMv2/src/lib/crypto/test/ECDSATests.h65
-rw-r--r--SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp304
-rw-r--r--SoftHSMv2/src/lib/crypto/test/GOSTTests.h76
-rw-r--r--SoftHSMv2/src/lib/crypto/test/HashTests.cpp269
-rw-r--r--SoftHSMv2/src/lib/crypto/test/HashTests.h73
-rw-r--r--SoftHSMv2/src/lib/crypto/test/MacTests.cpp687
-rw-r--r--SoftHSMv2/src/lib/crypto/test/MacTests.h83
-rw-r--r--SoftHSMv2/src/lib/crypto/test/Makefile.am39
-rw-r--r--SoftHSMv2/src/lib/crypto/test/RNGTests.cpp85
-rw-r--r--SoftHSMv2/src/lib/crypto/test/RNGTests.h59
-rw-r--r--SoftHSMv2/src/lib/crypto/test/RSATests.cpp682
-rw-r--r--SoftHSMv2/src/lib/crypto/test/RSATests.h67
-rw-r--r--SoftHSMv2/src/lib/crypto/test/chisq.c144
-rw-r--r--SoftHSMv2/src/lib/crypto/test/cryptotest.cpp91
-rw-r--r--SoftHSMv2/src/lib/crypto/test/ent.c110
-rw-r--r--SoftHSMv2/src/lib/crypto/test/ent.h56
-rw-r--r--SoftHSMv2/src/lib/crypto/test/iso8859.c25
-rw-r--r--SoftHSMv2/src/lib/crypto/test/iso8859.h23
-rw-r--r--SoftHSMv2/src/lib/crypto/test/randtest.c190
-rw-r--r--SoftHSMv2/src/lib/crypto/test/randtest.h13
246 files changed, 37145 insertions, 0 deletions
diff --git a/SoftHSMv2/src/lib/crypto/AESKey.cpp b/SoftHSMv2/src/lib/crypto/AESKey.cpp
new file mode 100644
index 0000000..9b511b5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AESKey.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AESKey.cpp
+
+ AES key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+#include "AESKey.h"
+#include "CryptoFactory.h"
+
+// Get key check value
+ByteString AESKey::getKeyCheckValue() const
+{
+ ByteString iv;
+ ByteString data;
+ ByteString encryptedData;
+ ByteString encryptedFinal;
+
+ SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::AES);
+ if (cipher == NULL) return encryptedData;
+
+ // Single block of null (0x00) bytes
+ data.resize(cipher->getBlockSize());
+ memset(&data[0], 0, data.size());
+
+ if (!cipher->encryptInit(this, SymMode::ECB, iv, false) ||
+ !cipher->encryptUpdate(data, encryptedData) ||
+ !cipher->encryptFinal(encryptedFinal))
+ {
+ CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
+ return encryptedData;
+ }
+ CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
+
+ encryptedData += encryptedFinal;
+ encryptedData.resize(3);
+
+ return encryptedData;
+}
diff --git a/SoftHSMv2/src/lib/crypto/AESKey.h b/SoftHSMv2/src/lib/crypto/AESKey.h
new file mode 100644
index 0000000..6505b9d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AESKey.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AESKey.h
+
+ AES key symmetric key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_AESKEY_H
+#define _SOFTHSM_V2_AESKEY_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "SymmetricKey.h"
+
+class AESKey : public SymmetricKey
+{
+public:
+ // Base constructor
+ AESKey(size_t inBitLen = 0) : SymmetricKey(inBitLen) { }
+
+ // Get the key check value
+ virtual ByteString getKeyCheckValue() const;
+};
+
+#endif // !SOFTHSM_V2_AESKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.cpp
new file mode 100644
index 0000000..20a50a5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AsymmetricAlgorithm.cpp
+
+ Base class for asymmetric algorithm classes
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "AsymmetricAlgorithm.h"
+
+// Base constructor
+AsymmetricAlgorithm::AsymmetricAlgorithm()
+{
+ currentOperation = NONE;
+ currentMechanism = AsymMech::Unknown;
+ currentPadding = AsymMech::Unknown;
+ currentPublicKey = NULL;
+ currentPrivateKey = NULL;
+}
+
+// Signing functions
+bool AsymmetricAlgorithm::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ // Compose from multi-part operations
+ return (signInit(privateKey, mechanism, param, paramLen) && signUpdate(dataToSign) && signFinal(signature));
+}
+
+bool AsymmetricAlgorithm::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ if ((currentOperation != NONE) || (privateKey == NULL))
+ {
+ return false;
+ }
+
+ currentPrivateKey = privateKey;
+ currentMechanism = mechanism;
+ currentOperation = SIGN;
+
+ return true;
+}
+
+bool AsymmetricAlgorithm::signUpdate(const ByteString& /*dataToSign*/)
+{
+ if (currentOperation != SIGN)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool AsymmetricAlgorithm::signFinal(ByteString& /*signature*/)
+{
+ if (currentOperation != SIGN)
+ {
+ return false;
+ }
+
+ currentOperation = NONE;
+ currentPrivateKey = NULL;
+ currentMechanism = AsymMech::Unknown;
+
+ return true;
+}
+
+// Verification functions
+bool AsymmetricAlgorithm::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ // Compose from multi-part operations
+ return (verifyInit(publicKey, mechanism, param, paramLen) && verifyUpdate(originalData) && verifyFinal(signature));
+}
+
+bool AsymmetricAlgorithm::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ if ((currentOperation != NONE) || (publicKey == NULL))
+ {
+ return false;
+ }
+
+ currentOperation = VERIFY;
+ currentPublicKey = publicKey;
+ currentMechanism = mechanism;
+
+ return true;
+}
+
+bool AsymmetricAlgorithm::verifyUpdate(const ByteString& /*originalData*/)
+{
+ if (currentOperation != VERIFY)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool AsymmetricAlgorithm::verifyFinal(const ByteString& /*signature*/)
+{
+ if (currentOperation != VERIFY)
+ {
+ return false;
+ }
+
+ currentOperation = NONE;
+ currentPublicKey = NULL;
+ currentMechanism = AsymMech::Unknown;
+
+ return true;
+}
+
+// Returns true for mechanisms which have 'tick mark' in Wrap&Unwrap column in PKCS #11 Mechanisms v2.40
+bool AsymmetricAlgorithm::isWrappingMech(AsymMech::Type padding)
+{
+ switch (padding)
+ {
+ case AsymMech::RSA:
+ case AsymMech::RSA_PKCS:
+ case AsymMech::RSA_PKCS_OAEP:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// Wrap/Unwrap keys
+bool AsymmetricAlgorithm::wrapKey(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding)
+{
+ if (!isWrappingMech(padding))
+ return false;
+
+ return encrypt(publicKey, data, encryptedData, padding);
+}
+
+bool AsymmetricAlgorithm::unwrapKey(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding)
+{
+ if (!isWrappingMech(padding))
+ return false;
+
+ return decrypt(privateKey, encryptedData, data, padding);
+}
+
+
+bool AsymmetricAlgorithm::generateParameters(AsymmetricParameters** /*ppParams*/, void* /*parameters = NULL*/, RNG* /*rng = NULL*/)
+{
+ return false;
+}
+
+bool AsymmetricAlgorithm::deriveKey(SymmetricKey** /*ppSymmetricKey*/, PublicKey* /*publicKey*/, PrivateKey* /*privateKey*/)
+{
+ return false;
+}
+
+bool AsymmetricAlgorithm::reconstructParameters(AsymmetricParameters** /*ppParams*/, ByteString& /*serialisedData*/)
+{
+ return false;
+}
+
+AsymmetricParameters* AsymmetricAlgorithm::newParameters()
+{
+ return NULL;
+}
+
+// Key recycling -- override these functions in a derived class if you need to perform specific cleanup
+void AsymmetricAlgorithm::recycleKeyPair(AsymmetricKeyPair* toRecycle)
+{
+ delete toRecycle;
+}
+
+void AsymmetricAlgorithm::recycleParameters(AsymmetricParameters* toRecycle)
+{
+ delete toRecycle;
+}
+
+void AsymmetricAlgorithm::recyclePublicKey(PublicKey* toRecycle)
+{
+ delete toRecycle;
+}
+
+void AsymmetricAlgorithm::recyclePrivateKey(PrivateKey* toRecycle)
+{
+ delete toRecycle;
+}
+
+void AsymmetricAlgorithm::recycleSymmetricKey(SymmetricKey* toRecycle)
+{
+ delete toRecycle;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h b/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h
new file mode 100644
index 0000000..ca0d840
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AsymmetricAlgorithm.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AsymmetricAlgorithm.h
+
+ Base class for asymmetric algorithm classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ASYMMETRICALGORITHM_H
+#define _SOFTHSM_V2_ASYMMETRICALGORITHM_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricParameters.h"
+#include "HashAlgorithm.h"
+#include "PublicKey.h"
+#include "PrivateKey.h"
+#include "RNG.h"
+#include "SymmetricKey.h"
+
+struct AsymAlgo
+{
+ enum Type
+ {
+ Unknown,
+ RSA,
+ DSA,
+ DH,
+ ECDH,
+ ECDSA,
+ GOST
+ };
+};
+
+struct AsymMech
+{
+ enum Type
+ {
+ Unknown,
+ RSA,
+ RSA_MD5_PKCS,
+ RSA_PKCS,
+ RSA_PKCS_OAEP,
+ RSA_SHA1_PKCS,
+ RSA_SHA224_PKCS,
+ RSA_SHA256_PKCS,
+ RSA_SHA384_PKCS,
+ RSA_SHA512_PKCS,
+ RSA_PKCS_PSS,
+ RSA_SHA1_PKCS_PSS,
+ RSA_SHA224_PKCS_PSS,
+ RSA_SHA256_PKCS_PSS,
+ RSA_SHA384_PKCS_PSS,
+ RSA_SHA512_PKCS_PSS,
+ RSA_SSL,
+ DSA,
+ DSA_SHA1,
+ DSA_SHA224,
+ DSA_SHA256,
+ DSA_SHA384,
+ DSA_SHA512,
+ ECDSA,
+ GOST,
+ GOST_GOST
+ };
+};
+
+struct AsymRSAMGF
+{
+ enum Type
+ {
+ Unknown,
+ MGF1_SHA1,
+ MGF1_SHA224,
+ MGF1_SHA256,
+ MGF1_SHA384,
+ MGF1_SHA512
+ };
+};
+
+struct RSA_PKCS_PSS_PARAMS
+{
+ HashAlgo::Type hashAlg;
+ AsymRSAMGF::Type mgf;
+ size_t sLen;
+};
+
+class AsymmetricAlgorithm
+{
+public:
+ // Base constructors
+ AsymmetricAlgorithm();
+
+ // Destructor
+ virtual ~AsymmetricAlgorithm() { }
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding) = 0;
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding) = 0;
+
+ // Wrap/Unwrap keys
+ bool wrapKey(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+ bool unwrapKey(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL) = 0;
+ virtual unsigned long getMinKeySize() = 0;
+ virtual unsigned long getMaxKeySize() = 0;
+ virtual bool generateParameters(AsymmetricParameters** ppParams, void* parameters = NULL, RNG* rng = NULL);
+ virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData) = 0;
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData) = 0;
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData) = 0;
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey() = 0;
+ virtual PrivateKey* newPrivateKey() = 0;
+ virtual AsymmetricParameters* newParameters();
+
+ // Key recycling -- override these functions in a derived class if you need to perform specific cleanup
+ virtual void recycleKeyPair(AsymmetricKeyPair* toRecycle);
+ virtual void recycleParameters(AsymmetricParameters* toRecycle);
+ virtual void recyclePublicKey(PublicKey* toRecycle);
+ virtual void recyclePrivateKey(PrivateKey* toRecycle);
+ virtual void recycleSymmetricKey(SymmetricKey* toRecycle);
+
+protected:
+ PublicKey* currentPublicKey;
+ PrivateKey* currentPrivateKey;
+
+ AsymMech::Type currentMechanism;
+ AsymMech::Type currentPadding;
+
+private:
+ enum
+ {
+ NONE,
+ SIGN,
+ VERIFY
+ }
+ currentOperation;
+
+ bool isWrappingMech(AsymMech::Type padding);
+};
+
+#endif // !_SOFTHSM_V2_ASYMMETRICALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.cpp b/SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.cpp
new file mode 100644
index 0000000..a31c17e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AsymmetricKeyPair.cpp
+
+ Asymmetric key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "AsymmetricKeyPair.h"
+
+ByteString AsymmetricKeyPair::serialise() const
+{
+ return getConstPublicKey()->serialise().serialise() + getConstPrivateKey()->serialise().serialise();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.h b/SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.h
new file mode 100644
index 0000000..8ff63ef
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AsymmetricKeyPair.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AsymmetricKeyPair.h
+
+ Base class for asymmetric key-pair classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ASYMMETRICKEYPAIR_H
+#define _SOFTHSM_V2_ASYMMETRICKEYPAIR_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "PublicKey.h"
+#include "PrivateKey.h"
+#include "Serialisable.h"
+
+class AsymmetricKeyPair : public Serialisable
+{
+public:
+ // Base constructors
+ AsymmetricKeyPair() { }
+
+ AsymmetricKeyPair(const AsymmetricKeyPair& /*in*/) { }
+
+ // Destructor
+ virtual ~AsymmetricKeyPair() { }
+
+ // Return the public key
+ virtual PublicKey* getPublicKey() = 0;
+ virtual const PublicKey* getConstPublicKey() const = 0;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey() = 0;
+ virtual const PrivateKey* getConstPrivateKey() const = 0;
+
+ // Serialise the contents
+ virtual ByteString serialise() const;
+};
+
+#endif // !_SOFTHSM_V2_ASYMMETRICKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/AsymmetricParameters.h b/SoftHSMv2/src/lib/crypto/AsymmetricParameters.h
new file mode 100644
index 0000000..12c607b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/AsymmetricParameters.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AsymmetricParameters.h
+
+ Base class for asymmetric parameter classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ASYMMETRICPARAMETERS_H
+#define _SOFTHSM_V2_ASYMMETRICPARAMETERS_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+
+class AsymmetricParameters : public Serialisable
+{
+public:
+ // Base constructors
+ AsymmetricParameters() { }
+
+ AsymmetricParameters(const AsymmetricParameters& /*in*/) { }
+
+ // Destructor
+ virtual ~AsymmetricParameters() { }
+
+ // Check if it is of the given type
+ virtual bool areOfType(const char* type) = 0;
+
+ // Serialisation
+ virtual ByteString serialise() const = 0;
+};
+
+#endif // !_SOFTHSM_V2_ASYMMETRICPARAMETERS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanAES.cpp b/SoftHSMv2/src/lib/crypto/BotanAES.cpp
new file mode 100644
index 0000000..0c67a09
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanAES.cpp
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanAES.cpp
+
+ Botan AES implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanAES.h"
+#include <algorithm>
+#include <botan/rfc3394.h>
+#include <botan/version.h>
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+#include <botan/libstate.h>
+#endif
+
+// Wrap/Unwrap keys
+bool BotanAES::wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out)
+{
+ // Check key bit length; AES only supports 128, 192 or 256 bit keys
+ if ((key->getBitLen() != 128) &&
+ (key->getBitLen() != 192) &&
+ (key->getBitLen() != 256))
+ {
+ ERROR_MSG("Invalid AES key length (%d bits)", key->getBitLen());
+
+ return false;
+ }
+
+ // Determine the wrapping mode
+ if (mode == SymWrap::AES_KEYWRAP)
+ {
+ // RFC 3394 AES key wrap
+ if (in.size() < 16)
+ {
+ ERROR_MSG("key data to wrap too small");
+
+ return false;
+ }
+ if ((in.size() % 8) != 0)
+ {
+ ERROR_MSG("key data to wrap not aligned");
+
+ return false;
+ }
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> data(in.size());
+ memcpy(data.data(), in.const_byte_str(), in.size());
+ Botan::secure_vector<Botan::byte> wrapped;
+#else
+ Botan::MemoryVector<Botan::byte> data(in.size());
+ memcpy(data.begin(), in.const_byte_str(), in.size());
+ Botan::SecureVector<Botan::byte> wrapped;
+#endif
+ Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
+ try
+ {
+ wrapped = Botan::rfc3394_keywrap(data, botanKey, af);
+ }
+#else
+ try
+ {
+ wrapped = Botan::rfc3394_keywrap(data, botanKey);
+ }
+#endif
+ catch (...)
+ {
+ ERROR_MSG("AES key wrap failed");
+
+ return false;
+ }
+ out.resize(wrapped.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&out[0], wrapped.data(), out.size());
+#else
+ memcpy(&out[0], wrapped.begin(), out.size());
+#endif
+
+ return true;
+ }
+#ifdef HAVE_AES_KEY_WRAP_PAD
+ else if (mode == SymWrap::AES_KEYWRAP_PAD)
+ {
+ // RFC 5649 AES key wrap with pad
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> data(in.size());
+ memcpy(data.data(), in.const_byte_str(), in.size());
+ Botan::secure_vector<Botan::byte> wrapped;
+#else
+ Botan::MemoryVector<Botan::byte> data(in.size());
+ memcpy(data.begin(), in.const_byte_str(), in.size());
+ Botan::SecureVector<Botan::byte> wrapped;
+#endif
+ Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
+ try
+ {
+ wrapped = Botan::rfc5649_keywrap(data, botanKey, af);
+ }
+#else
+ try
+ {
+ wrapped = Botan::rfc5649_keywrap(data, botanKey);
+ }
+#endif
+ catch (...)
+ {
+ ERROR_MSG("AES key wrap failed");
+
+ return false;
+ }
+ out.resize(wrapped.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&out[0], wrapped.data(), out.size());
+#else
+ memcpy(&out[0], wrapped.begin(), out.size());
+#endif
+
+ return true;
+ }
+#endif
+ else
+ {
+ ERROR_MSG("unknown AES key wrap mode %i", mode);
+
+ return false;
+ }
+}
+
+bool BotanAES::unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out)
+{
+ // Check key bit length; AES only supports 128, 192 or 256 bit keys
+ if ((key->getBitLen() != 128) &&
+ (key->getBitLen() != 192) &&
+ (key->getBitLen() != 256))
+ {
+ ERROR_MSG("Invalid AES key length (%d bits)", key->getBitLen());
+
+ return false;
+ }
+
+ // Determine the unwrapping mode
+ if (mode == SymWrap::AES_KEYWRAP)
+ {
+ // RFC 3394 AES key wrap
+ if (in.size() < 24)
+ {
+ ERROR_MSG("key data to unwrap too small");
+
+ return false;
+ }
+ if ((in.size() % 8) != 0)
+ {
+ ERROR_MSG("key data to unwrap not aligned");
+
+ return false;
+ }
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> wrapped(in.size());
+ memcpy(wrapped.data(), in.const_byte_str(), in.size());
+ Botan::secure_vector<Botan::byte> unwrapped;
+#else
+ Botan::MemoryVector<Botan::byte> wrapped(in.size());
+ memcpy(wrapped.begin(), in.const_byte_str(), in.size());
+ Botan::SecureVector<Botan::byte> unwrapped;
+#endif
+ Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
+ try
+ {
+ unwrapped = Botan::rfc3394_keyunwrap(wrapped, botanKey, af);
+ }
+#else
+ try
+ {
+ unwrapped = Botan::rfc3394_keyunwrap(wrapped, botanKey);
+ }
+#endif
+ catch (...)
+ {
+ ERROR_MSG("AES key unwrap failed");
+
+ return false;
+ }
+ out.resize(unwrapped.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&out[0], unwrapped.data(), out.size());
+#else
+ memcpy(&out[0], unwrapped.begin(), out.size());
+#endif
+
+ return true;
+ }
+#ifdef HAVE_AES_KEY_WRAP_PAD
+ else if (mode == SymWrap::AES_KEYWRAP_PAD)
+ {
+ // RFC 5649 AES key wrap with wrap
+ if (in.size() < 16)
+ {
+ ERROR_MSG("key data to unwrap too small");
+
+ return false;
+ }
+ if ((in.size() % 8) != 0)
+ {
+ ERROR_MSG("key data to unwrap not aligned");
+
+ return false;
+ }
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> wrapped(in.size());
+ memcpy(wrapped.data(), in.const_byte_str(), in.size());
+ Botan::secure_vector<Botan::byte> unwrapped;
+#else
+ Botan::MemoryVector<Botan::byte> wrapped(in.size());
+ memcpy(wrapped.begin(), in.const_byte_str(), in.size());
+ Botan::SecureVector<Botan::byte> unwrapped;
+#endif
+ Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
+ try
+ {
+ unwrapped = Botan::rfc5649_keyunwrap(wrapped, botanKey, af);
+ }
+#else
+ try
+ {
+ unwrapped = Botan::rfc5649_keyunwrap(wrapped, botanKey);
+ }
+#endif
+ catch (...)
+ {
+ ERROR_MSG("AES key unwrap failed");
+
+ return false;
+ }
+ out.resize(unwrapped.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&out[0], unwrapped.data(), out.size());
+#else
+ memcpy(&out[0], unwrapped.begin(), out.size());
+#endif
+
+ return true;
+ }
+#endif
+ else
+ {
+ ERROR_MSG("unknown AES key wrap mode %i", mode);
+
+ return false;
+ }
+}
+
+std::string BotanAES::getCipher() const
+{
+ std::string algo;
+ std::string mode;
+ std::string padding;
+
+ if (currentKey == NULL) return "";
+
+ // Check currentKey bit length; AES only supports 128, 192 or 256 bit keys
+ switch (currentKey->getBitLen())
+ {
+ case 128:
+ algo = "AES-128";
+ break;
+ case 192:
+ algo = "AES-192";
+ break;
+ case 256:
+ algo = "AES-256";
+ break;
+ default:
+ ERROR_MSG("Invalid AES currentKey length (%d bits)", currentKey->getBitLen());
+
+ return "";
+ }
+
+ // Determine the cipher mode
+ switch (currentCipherMode)
+ {
+ case SymMode::CBC:
+ mode = "CBC";
+ break;
+ case SymMode::CTR:
+ return algo + "/CTR-BE";
+ case SymMode::ECB:
+ mode = "ECB";
+ break;
+#ifdef WITH_AES_GCM
+ case SymMode::GCM:
+ return algo + "/GCM(" + std::to_string(currentTagBytes) + ")";
+#endif
+ default:
+ ERROR_MSG("Invalid AES cipher mode %i", currentCipherMode);
+
+ return "";
+ }
+
+ // Check padding mode
+ if (currentPaddingMode)
+ {
+ padding = "PKCS7";
+ }
+ else
+ {
+ padding = "NoPadding";
+ }
+
+ return algo + "/" + mode + "/" + padding;
+}
+
+size_t BotanAES::getBlockSize() const
+{
+ // The block size is 128 bits
+ return 128 >> 3;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanAES.h b/SoftHSMv2/src/lib/crypto/BotanAES.h
new file mode 100644
index 0000000..4bc38ab
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanAES.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanAES.h
+
+ Botan AES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANAES_H
+#define _SOFTHSM_V2_BOTANAES_H
+
+#include <string>
+#include "config.h"
+#include "BotanSymmetricAlgorithm.h"
+
+class BotanAES : public BotanSymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~BotanAES() { }
+
+ // Wrap/Unwrap keys
+ virtual bool wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ virtual bool unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ // Return the block size
+ virtual size_t getBlockSize() const;
+
+protected:
+ // Return the right Botan cipher for the operation
+ virtual std::string getCipher() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANAES_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp
new file mode 100644
index 0000000..b4df224
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanCryptoFactory.cpp
+
+ This is a Botan based cryptographic algorithm factory
+ *****************************************************************************/
+#include "config.h"
+#include "BotanCryptoFactory.h"
+#include "BotanAES.h"
+#include "BotanDES.h"
+#include "BotanDSA.h"
+#include "BotanDH.h"
+#ifdef WITH_ECC
+#include "BotanECDH.h"
+#include "BotanECDSA.h"
+#endif
+#include "BotanMD5.h"
+#include "BotanRNG.h"
+#include "BotanRSA.h"
+#include "BotanSHA1.h"
+#include "BotanSHA224.h"
+#include "BotanSHA256.h"
+#include "BotanSHA384.h"
+#include "BotanSHA512.h"
+#ifdef WITH_GOST
+#include "BotanGOST.h"
+#include "BotanGOSTR3411.h"
+#endif
+#include "BotanMAC.h"
+
+#include <botan/init.h>
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+#include <botan/libstate.h>
+#endif
+
+// Constructor
+BotanCryptoFactory::BotanCryptoFactory()
+{
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ wasInitialized = false;
+
+ // Check if Botan has already been initialized
+ if (Botan::Global_State_Management::global_state_exists())
+ {
+ wasInitialized = true;
+ }
+
+ // Init the Botan crypto library
+ if (!wasInitialized)
+ {
+ Botan::LibraryInitializer::initialize("thread_safe=true");
+ }
+#else
+ Botan::LibraryInitializer::initialize("thread_safe=true");
+#endif
+
+ // Create mutex
+ rngsMutex = MutexFactory::i()->getMutex();
+}
+
+// Destructor
+BotanCryptoFactory::~BotanCryptoFactory()
+{
+ // Delete the RNGs
+#ifdef HAVE_PTHREAD_H
+ std::map<pthread_t,RNG*>::iterator it;
+ for (it=rngs.begin(); it != rngs.end(); it++)
+ {
+ delete (BotanRNG*)it->second;
+ }
+#elif _WIN32
+ std::map<DWORD,RNG*>::iterator it;
+ for (it=rngs.begin(); it != rngs.end(); it++)
+ {
+ delete (BotanRNG*)it->second;
+ }
+#endif
+
+ // Delete the mutex
+ MutexFactory::i()->recycleMutex(rngsMutex);
+
+ // Deinitialize the Botan crypto lib
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ if (!wasInitialized)
+ {
+ Botan::LibraryInitializer::deinitialize();
+ }
+#else
+ Botan::LibraryInitializer::deinitialize();
+#endif
+}
+
+// Return the one-and-only instance
+BotanCryptoFactory* BotanCryptoFactory::i()
+{
+ if (!instance.get())
+ {
+ instance.reset(new BotanCryptoFactory());
+ }
+
+ return instance.get();
+}
+
+// This will destroy the one-and-only instance.
+void BotanCryptoFactory::reset()
+{
+ instance.reset();
+}
+
+// Create a concrete instance of a symmetric algorithm
+SymmetricAlgorithm* BotanCryptoFactory::getSymmetricAlgorithm(SymAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case SymAlgo::AES:
+ return new BotanAES();
+ case SymAlgo::DES:
+ case SymAlgo::DES3:
+ return new BotanDES();
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of an asymmetric algorithm
+AsymmetricAlgorithm* BotanCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case AsymAlgo::RSA:
+ return new BotanRSA();
+ case AsymAlgo::DSA:
+ return new BotanDSA();
+ case AsymAlgo::DH:
+ return new BotanDH();
+#ifdef WITH_ECC
+ case AsymAlgo::ECDH:
+ return new BotanECDH();
+ case AsymAlgo::ECDSA:
+ return new BotanECDSA();
+#endif
+#ifdef WITH_GOST
+ case AsymAlgo::GOST:
+ return new BotanGOST();
+#endif
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of a hash algorithm
+HashAlgorithm* BotanCryptoFactory::getHashAlgorithm(HashAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case HashAlgo::MD5:
+ return new BotanMD5();
+ case HashAlgo::SHA1:
+ return new BotanSHA1();
+ case HashAlgo::SHA224:
+ return new BotanSHA224();
+ case HashAlgo::SHA256:
+ return new BotanSHA256();
+ case HashAlgo::SHA384:
+ return new BotanSHA384();
+ case HashAlgo::SHA512:
+ return new BotanSHA512();
+#ifdef WITH_GOST
+ case HashAlgo::GOST:
+ return new BotanGOSTR3411();
+#endif
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of a MAC algorithm
+MacAlgorithm* BotanCryptoFactory::getMacAlgorithm(MacAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case MacAlgo::HMAC_MD5:
+ return new BotanHMACMD5();
+ case MacAlgo::HMAC_SHA1:
+ return new BotanHMACSHA1();
+ case MacAlgo::HMAC_SHA224:
+ return new BotanHMACSHA224();
+ case MacAlgo::HMAC_SHA256:
+ return new BotanHMACSHA256();
+ case MacAlgo::HMAC_SHA384:
+ return new BotanHMACSHA384();
+ case MacAlgo::HMAC_SHA512:
+ return new BotanHMACSHA512();
+#ifdef WITH_GOST
+ case MacAlgo::HMAC_GOST:
+ return new BotanHMACGOSTR3411();
+#endif
+ case MacAlgo::CMAC_DES:
+ return new BotanCMACDES();
+ case MacAlgo::CMAC_AES:
+ return new BotanCMACAES();
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Get the global RNG (may be an unique RNG per thread)
+RNG* BotanCryptoFactory::getRNG(RNGImpl::Type name /* = RNGImpl::Default */)
+{
+ if (name == RNGImpl::Default)
+ {
+ RNG *threadRNG = NULL;
+
+ // Lock access to the map
+ MutexLocker lock(rngsMutex);
+
+#ifdef HAVE_PTHREAD_H
+ // Get thread ID
+ pthread_t threadID = pthread_self();
+
+ // Find the RNG
+ std::map<pthread_t,RNG*>::iterator findIt;
+ findIt=rngs.find(threadID);
+ if (findIt != rngs.end())
+ {
+ return findIt->second;
+ }
+
+ threadRNG = new BotanRNG();
+ rngs[threadID] = threadRNG;
+#elif _WIN32
+ // Get thread ID
+ DWORD threadID = GetCurrentThreadId();
+
+ // Find the RNG
+ std::map<DWORD,RNG*>::iterator findIt;
+ findIt=rngs.find(threadID);
+ if (findIt != rngs.end())
+ {
+ return findIt->second;
+ }
+
+ threadRNG = new BotanRNG();
+ rngs[threadID] = threadRNG;
+#else
+#error "There are no thread-specific data implementations for your operating system yet"
+#endif
+ return threadRNG;
+ }
+ else
+ {
+ // No RNG implementation is available
+ ERROR_MSG("Unknown RNG '%i'", name);
+
+ return NULL;
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.h b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.h
new file mode 100644
index 0000000..df7556d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanCryptoFactory.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanCryptoFactory.h
+
+ This is a Botan based cryptographic algorithm factory
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANCRYPTOFACTORY_H
+#define _SOFTHSM_V2_BOTANCRYPTOFACTORY_H
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#include "config.h"
+#include "CryptoFactory.h"
+#include "SymmetricAlgorithm.h"
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+#include "MutexFactory.h"
+#include <memory>
+#include <map>
+#include <botan/version.h>
+
+class BotanCryptoFactory : public CryptoFactory
+{
+public:
+ // Return the one-and-only instance
+ static BotanCryptoFactory* i();
+
+ // This will destroy the one-and-only instance.
+ static void reset();
+
+ // Create a concrete instance of a symmetric algorithm
+ SymmetricAlgorithm* getSymmetricAlgorithm(SymAlgo::Type algorithm);
+
+ // Create a concrete instance of an asymmetric algorithm
+ AsymmetricAlgorithm* getAsymmetricAlgorithm(AsymAlgo::Type algorithm);
+
+ // Create a concrete instance of a hash algorithm
+ HashAlgorithm* getHashAlgorithm(HashAlgo::Type algorithm);
+
+ // Create a concrete instance of a MAC algorithm
+ MacAlgorithm* getMacAlgorithm(MacAlgo::Type algorithm);
+
+ // Get the global RNG (may be an unique RNG per thread)
+ RNG* getRNG(RNGImpl::Type name = RNGImpl::Default);
+
+ // Destructor
+ ~BotanCryptoFactory();
+
+private:
+ // Constructor
+ BotanCryptoFactory();
+
+ // The one-and-only instance
+#ifdef HAVE_CXX11
+ static std::unique_ptr<BotanCryptoFactory> instance;
+#else
+ static std::auto_ptr<BotanCryptoFactory> instance;
+#endif
+
+ // Thread specific RNG
+#ifdef HAVE_PTHREAD_H
+ std::map<pthread_t, RNG*> rngs;
+#elif _WIN32
+ std::map<DWORD, RNG*> rngs;
+#endif
+ Mutex* rngsMutex;
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ bool wasInitialized;
+#endif
+};
+
+#endif // !_SOFTHSM_V2_BOTANCRYPTOFACTORY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDES.cpp b/SoftHSMv2/src/lib/crypto/BotanDES.cpp
new file mode 100644
index 0000000..393cf4d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDES.cpp
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDES.cpp
+
+ Botan (3)DES implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanDES.h"
+#include <algorithm>
+#include "odd.h"
+
+bool BotanDES::wrapKey(const SymmetricKey* /*key*/, const SymWrap::Type /*mode*/, const ByteString& /*in*/, ByteString& /*out*/)
+{
+ ERROR_MSG("DES does not support key wrapping");
+
+ return false;
+}
+
+bool BotanDES::unwrapKey(const SymmetricKey* /*key*/, const SymWrap::Type /*mode*/, const ByteString& /*in*/, ByteString& /*out*/)
+{
+ ERROR_MSG("DES does not support key unwrapping");
+
+ return false;
+}
+
+std::string BotanDES::getCipher() const
+{
+ std::string algo;
+ std::string mode;
+ std::string padding;
+
+ if (currentKey == NULL) return "";
+
+ // Check currentKey bit length; 3DES only supports 56-bit, 112-bit or 168-bit keys
+ switch (currentKey->getBitLen())
+ {
+ case 56:
+ // People shouldn't really be using 56-bit DES keys, generate a warning
+ DEBUG_MSG("CAUTION: use of 56-bit DES keys is not recommended!");
+ algo = "DES";
+ break;
+ case 112:
+ case 168:
+ algo = "TripleDES";
+ break;
+ default:
+ ERROR_MSG("Invalid DES currentKey length (%d bits)", currentKey->getBitLen());
+
+ return "";
+ }
+
+ // Determine the cipher mode
+ switch (currentCipherMode)
+ {
+ case SymMode::CBC:
+ mode = "CBC";
+ break;
+ case SymMode::CFB:
+ mode = "CFB";
+ break;
+ case SymMode::ECB:
+ mode = "ECB";
+ break;
+ case SymMode::OFB:
+ mode = "OFB";
+ break;
+ default:
+ ERROR_MSG("Invalid DES cipher mode %i", currentCipherMode);
+
+ return "";
+ }
+
+ // Check padding mode
+ if (currentCipherMode == SymMode::OFB ||
+ currentCipherMode == SymMode::CFB)
+ {
+ padding = "";
+ }
+ else if (currentPaddingMode)
+ {
+ padding = "/PKCS7";
+ }
+ else
+ {
+ padding = "/NoPadding";
+ }
+
+ return algo + "/" + mode + padding;
+}
+
+bool BotanDES::generateKey(SymmetricKey& key, RNG* rng /* = NULL */)
+{
+ if (rng == NULL)
+ {
+ return false;
+ }
+
+ if (key.getBitLen() == 0)
+ {
+ return false;
+ }
+
+ ByteString keyBits;
+
+ // don't count parity bit
+ if (!rng->generateRandom(keyBits, key.getBitLen()/7))
+ {
+ return false;
+ }
+
+ // fix the odd parity
+ size_t i;
+ for (i = 0; i < keyBits.size(); i++)
+ {
+ keyBits[i] = odd_parity[keyBits[i]];
+ }
+
+
+ return key.setKeyBits(keyBits);
+}
+
+size_t BotanDES::getBlockSize() const
+{
+ // The block size is 64 bits
+ return 64 >> 3;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDES.h b/SoftHSMv2/src/lib/crypto/BotanDES.h
new file mode 100644
index 0000000..4f81fe6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDES.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDES.h
+
+ Botan (3)DES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDES_H
+#define _SOFTHSM_V2_BOTANDES_H
+
+#include <string>
+#include "config.h"
+#include "BotanSymmetricAlgorithm.h"
+
+class BotanDES : public BotanSymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~BotanDES() { }
+
+ // Wrap/Unwrap keys
+ virtual bool wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ virtual bool unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ // Generate key
+ virtual bool generateKey(SymmetricKey& key, RNG* rng = NULL);
+
+ // Return the block size
+ virtual size_t getBlockSize() const;
+
+protected:
+ // Return the right Botan cipher for the operation
+ virtual std::string getCipher() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANDES_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDH.cpp b/SoftHSMv2/src/lib/crypto/BotanDH.cpp
new file mode 100644
index 0000000..5adc239
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDH.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDH.cpp
+
+ Botan Diffie-Hellman asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDH.h"
+#include "BotanRNG.h"
+#include "CryptoFactory.h"
+#include "BotanCryptoFactory.h"
+#include "DHParameters.h"
+#include "BotanDHKeyPair.h"
+#include "BotanUtil.h"
+#include <algorithm>
+#include <botan/dl_group.h>
+#include <botan/dh.h>
+#include <botan/pubkey.h>
+#include <botan/version.h>
+
+// Signing functions
+bool BotanDH::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("DH does not support signing");
+
+ return false;
+}
+
+bool BotanDH::signUpdate(const ByteString& /*dataToSign*/)
+{
+ ERROR_MSG("DH does not support signing");
+
+ return false;
+}
+
+bool BotanDH::signFinal(ByteString& /*signature*/)
+{
+ ERROR_MSG("DH does not support signing");
+
+ return false;
+}
+
+// Verification functions
+bool BotanDH::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("DH does not support verifying");
+
+ return false;
+}
+
+bool BotanDH::verifyUpdate(const ByteString& /*originalData*/)
+{
+ ERROR_MSG("DH does not support verifying");
+
+ return false;
+}
+
+bool BotanDH::verifyFinal(const ByteString& /*signature*/)
+{
+ ERROR_MSG("DH does not support verifying");
+
+ return false;
+}
+
+// Encryption functions
+bool BotanDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DH does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool BotanDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DH does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool BotanDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(DHParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for DH key generation");
+
+ return false;
+ }
+
+ DHParameters* params = (DHParameters*) parameters;
+
+ // Generate the key-pair
+ BotanDH_PrivateKey* dh = NULL;
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+
+ // PKCS#3: 2^(l-1) <= x < 2^l
+ Botan::BigInt x;
+ if (params->getXBitLength() > 0)
+ {
+ x.randomize(*rng->getRNG(), params->getXBitLength());
+ }
+
+ dh = new BotanDH_PrivateKey(*rng->getRNG(),
+ Botan::DL_Group(BotanUtil::byteString2bigInt(params->getP()),
+ BotanUtil::byteString2bigInt(params->getG())),
+ x);
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("DH key generation failed with %s", e.what());
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ BotanDHKeyPair* kp = new BotanDHKeyPair();
+
+ ((BotanDHPublicKey*) kp->getPublicKey())->setFromBotan(dh);
+ ((BotanDHPrivateKey*) kp->getPrivateKey())->setFromBotan(dh);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ delete dh;
+
+ return true;
+}
+
+bool BotanDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
+{
+ // Check parameters
+ if ((ppSymmetricKey == NULL) ||
+ (publicKey == NULL) ||
+ (privateKey == NULL))
+ {
+ return false;
+ }
+
+ // Get keys
+ Botan::DH_PublicKey* pub = ((BotanDHPublicKey*) publicKey)->getBotanKey();
+ BotanDH_PrivateKey* priv = ((BotanDHPrivateKey*) privateKey)->getBotanKey();
+ if (pub == NULL || priv == NULL || priv->impl == NULL)
+ {
+ ERROR_MSG("Failed to get Botan DH keys");
+
+ return false;
+ }
+
+ // Derive the secret
+ Botan::SymmetricKey sk;
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ Botan::PK_Key_Agreement ka(*priv->impl, *rng->getRNG(), "Raw");
+#else
+ Botan::PK_Key_Agreement ka(*priv->impl, "Raw");
+#endif
+ sk = ka.derive_key(0, pub->public_value());
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Botan DH key agreement failed: %s", e.what());
+
+ return false;
+ }
+
+ ByteString secret;
+
+ // We compensate that Botan removes leading zeros
+ int size = ((BotanDHPublicKey*) publicKey)->getOutputLength();
+ int keySize = sk.length();
+ secret.wipe(size);
+ memcpy(&secret[0] + size - keySize, sk.begin(), keySize);
+
+ *ppSymmetricKey = new SymmetricKey(secret.size() * 8);
+ if (*ppSymmetricKey == NULL)
+ {
+ ERROR_MSG("Can't create DH secret");
+
+ return false;
+ }
+ if (!(*ppSymmetricKey)->setKeyBits(secret))
+ {
+ delete *ppSymmetricKey;
+ *ppSymmetricKey = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+unsigned long BotanDH::getMinKeySize()
+{
+ return 512;
+}
+
+unsigned long BotanDH::getMaxKeySize()
+{
+ return 4096;
+}
+
+bool BotanDH::generateParameters(AsymmetricParameters** ppParams, void* parameters /* = NULL */, RNG* /*rng = NULL*/)
+{
+ if ((ppParams == NULL) || (parameters == NULL))
+ {
+ return false;
+ }
+
+ size_t bitLen = (size_t) parameters;
+
+ if (bitLen < getMinKeySize() || bitLen > getMaxKeySize())
+ {
+ ERROR_MSG("This DH key size is not supported");
+
+ return false;
+ }
+
+ Botan::DL_Group* group = NULL;
+ try
+ {
+ BotanRNG* brng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ group = new Botan::DL_Group(*brng->getRNG(), Botan::DL_Group::Strong, bitLen);
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Failed to generate %d bit DH parameters: %s", bitLen, e.what());
+
+ return false;
+ }
+
+ // Store the DH parameters
+ DHParameters* params = new DHParameters();
+
+ ByteString p = BotanUtil::bigInt2ByteString(group->get_p());
+ params->setP(p);
+ ByteString g = BotanUtil::bigInt2ByteString(group->get_g());
+ params->setG(g);
+
+ *ppParams = params;
+
+ delete group;
+
+ return true;
+}
+
+bool BotanDH::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ BotanDHKeyPair* kp = new BotanDHKeyPair();
+
+ bool rv = true;
+
+ if (!((DHPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((DHPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool BotanDH::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanDHPublicKey* pub = new BotanDHPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool BotanDH::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanDHPrivateKey* priv = new BotanDHPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* BotanDH::newPublicKey()
+{
+ return (PublicKey*) new BotanDHPublicKey();
+}
+
+PrivateKey* BotanDH::newPrivateKey()
+{
+ return (PrivateKey*) new BotanDHPrivateKey();
+}
+
+AsymmetricParameters* BotanDH::newParameters()
+{
+ return (AsymmetricParameters*) new DHParameters();
+}
+
+bool BotanDH::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ DHParameters* params = new DHParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDH.h b/SoftHSMv2/src/lib/crypto/BotanDH.h
new file mode 100644
index 0000000..af2ac59
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDH.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDH.h
+
+ Botan Diffie-Hellman asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDH_H
+#define _SOFTHSM_V2_BOTANDH_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <botan/pubkey.h>
+
+class BotanDH : public AsymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~BotanDH() { }
+
+ // Signing functions
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool generateParameters(AsymmetricParameters** ppParams, void* parameters = NULL, RNG* rng = NULL);
+ virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_BOTANDH_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDHKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanDHKeyPair.cpp
new file mode 100644
index 0000000..10c2131
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDHKeyPair.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDHKeyPair.cpp
+
+ Botan Diffie-Hellman key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDHKeyPair.h"
+
+// Set the public key
+void BotanDHKeyPair::setPublicKey(BotanDHPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void BotanDHKeyPair::setPrivateKey(BotanDHPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* BotanDHKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* BotanDHKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* BotanDHKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* BotanDHKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDHKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanDHKeyPair.h
new file mode 100644
index 0000000..629c6fd
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDHKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDHKeyPair.h
+
+ Botan DiffieHellman key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDHKEYPAIR_H
+#define _SOFTHSM_V2_BOTANDHKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "BotanDHPublicKey.h"
+#include "BotanDHPrivateKey.h"
+
+class BotanDHKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(BotanDHPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(BotanDHPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ BotanDHPublicKey pubKey;
+
+ // The private key
+ BotanDHPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_BOTANDHKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.cpp
new file mode 100644
index 0000000..cb7a530
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDHPrivateKey.cpp
+
+ Botan Diffie-Hellman private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDHPrivateKey.h"
+#include "BotanCryptoFactory.h"
+#include "BotanRNG.h"
+#include "BotanUtil.h"
+#include <string.h>
+#include <botan/pkcs8.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/oids.h>
+#include <botan/version.h>
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+std::vector<Botan::byte> BotanDH_PrivateKey::public_value() const
+{
+ return impl->public_value();
+}
+#else
+Botan::MemoryVector<Botan::byte> BotanDH_PrivateKey::public_value() const
+{
+ return impl->public_value();
+}
+#endif
+
+// Redefine of DH_PrivateKey constructor with the correct format
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+BotanDH_PrivateKey::BotanDH_PrivateKey(
+ const Botan::AlgorithmIdentifier& alg_id,
+ const Botan::secure_vector<Botan::byte>& key_bits,
+ Botan::RandomNumberGenerator& rng) :
+ Botan::DL_Scheme_PrivateKey(alg_id, key_bits, Botan::DL_Group::PKCS3_DH_PARAMETERS)
+{
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,27)
+ impl = new Botan::DH_PrivateKey(rng, m_group, m_x);
+#else
+ impl = new Botan::DH_PrivateKey(rng, group, x);
+#endif
+}
+#else
+BotanDH_PrivateKey::BotanDH_PrivateKey(
+ const Botan::AlgorithmIdentifier& alg_id,
+ const Botan::MemoryRegion<Botan::byte>& key_bits,
+ Botan::RandomNumberGenerator& rng) :
+ Botan::DL_Scheme_PrivateKey(alg_id, key_bits, Botan::DL_Group::PKCS3_DH_PARAMETERS)
+{
+ impl = new Botan::DH_PrivateKey(rng, group, x);
+}
+#endif
+
+BotanDH_PrivateKey::BotanDH_PrivateKey(Botan::RandomNumberGenerator& rng,
+ const Botan::DL_Group& grp,
+ const Botan::BigInt& x_arg)
+{
+ impl = new Botan::DH_PrivateKey(rng, grp, x_arg);
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,27)
+ m_group = grp;
+ m_x = x_arg;
+ m_y = impl->get_y();
+#else
+ group = grp;
+ x = x_arg;
+ y = impl->get_y();
+#endif
+}
+
+BotanDH_PrivateKey::~BotanDH_PrivateKey()
+{
+ delete impl;
+}
+
+// Constructors
+BotanDHPrivateKey::BotanDHPrivateKey()
+{
+ dh = NULL;
+}
+
+BotanDHPrivateKey::BotanDHPrivateKey(const BotanDH_PrivateKey* inDH)
+{
+ dh = NULL;
+
+ setFromBotan(inDH);
+}
+
+// Destructor
+BotanDHPrivateKey::~BotanDHPrivateKey()
+{
+ delete dh;
+}
+
+// The type
+/*static*/ const char* BotanDHPrivateKey::type = "Botan DH Private Key";
+
+// Set from Botan representation
+void BotanDHPrivateKey::setFromBotan(const BotanDH_PrivateKey* inDH)
+{
+ ByteString inP = BotanUtil::bigInt2ByteString(inDH->impl->group_p());
+ setP(inP);
+ ByteString inG = BotanUtil::bigInt2ByteString(inDH->impl->group_g());
+ setG(inG);
+ ByteString inX = BotanUtil::bigInt2ByteString(inDH->impl->get_x());
+ setX(inX);
+}
+
+// Check if the key is of the given type
+bool BotanDHPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DH private key components
+void BotanDHPrivateKey::setX(const ByteString& inX)
+{
+ DHPrivateKey::setX(inX);
+
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+}
+
+// Setters for the DH public key components
+void BotanDHPrivateKey::setP(const ByteString& inP)
+{
+ DHPrivateKey::setP(inP);
+
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+}
+
+void BotanDHPrivateKey::setG(const ByteString& inG)
+{
+ DHPrivateKey::setG(inG);
+
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString BotanDHPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ createBotanKey();
+ if (dh == NULL) return der;
+ // Force PKCS3_DH_PARAMETERS for p, g and no q.
+ const size_t PKCS8_VERSION = 0;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+ const std::vector<Botan::byte> parameters = dh->impl->get_domain().DER_encode(Botan::DL_Group::PKCS3_DH_PARAMETERS);
+ const Botan::AlgorithmIdentifier alg_id(dh->impl->get_oid(), parameters);
+ const Botan::secure_vector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(dh->impl->private_key_bits(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ const std::vector<Botan::byte> parameters = dh->impl->get_domain().DER_encode(Botan::DL_Group::PKCS3_DH_PARAMETERS);
+ const Botan::AlgorithmIdentifier alg_id(dh->impl->get_oid(), parameters);
+ const Botan::secure_vector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(dh->impl->pkcs8_private_key(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#else
+ const Botan::MemoryVector<Botan::byte> parameters = dh->impl->get_domain().DER_encode(Botan::DL_Group::PKCS3_DH_PARAMETERS);
+ const Botan::AlgorithmIdentifier alg_id(dh->impl->get_oid(), parameters);
+ const Botan::SecureVector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(dh->impl->pkcs8_private_key(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#endif
+ der.resize(ber.size());
+ memcpy(&der[0], &ber[0], ber.size());
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool BotanDHPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ Botan::DataSource_Memory source(ber.const_byte_str(), ber.size());
+ if (source.end_of_data()) return false;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> keydata;
+#else
+ Botan::SecureVector<Botan::byte> keydata;
+#endif
+ Botan::AlgorithmIdentifier alg_id;
+ BotanDH_PrivateKey* key = NULL;
+ try
+ {
+ Botan::BER_Decoder(source)
+ .start_cons(Botan::SEQUENCE)
+ .decode_and_check<size_t>(0, "Unknown PKCS #8 version number")
+ .decode(alg_id)
+ .decode(keydata, Botan::OCTET_STRING)
+ .discard_remaining()
+ .end_cons();
+ if (keydata.empty())
+ throw Botan::Decoding_Error("PKCS #8 private key decoding failed");
+ if (Botan::OIDS::lookup(alg_id.oid).compare("DH"))
+ {
+ ERROR_MSG("Decoded private key not DH");
+
+ return false;
+ }
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ key = new BotanDH_PrivateKey(alg_id, keydata, *rng->getRNG());
+ if (key == NULL) return false;
+
+ setFromBotan(key);
+
+ delete key;
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Decode failed on %s", e.what());
+
+ return false;
+ }
+
+ return true;
+}
+
+// Retrieve the Botan representation of the key
+BotanDH_PrivateKey* BotanDHPrivateKey::getBotanKey()
+{
+ if (!dh)
+ {
+ createBotanKey();
+ }
+
+ return dh;
+}
+
+// Create the Botan representation of the key
+void BotanDHPrivateKey::createBotanKey()
+{
+ // y is not needed
+ if (p.size() != 0 &&
+ g.size() != 0 &&
+ x.size() != 0)
+ {
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ dh = new BotanDH_PrivateKey(*rng->getRNG(),
+ Botan::DL_Group(BotanUtil::byteString2bigInt(p),
+ BotanUtil::byteString2bigInt(g)),
+ BotanUtil::byteString2bigInt(x));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.h
new file mode 100644
index 0000000..5991c21
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDHPrivateKey.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDHPrivateKey.h
+
+ Botan Diffie-Hellman private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDHPRIVATEKEY_H
+#define _SOFTHSM_V2_BOTANDHPRIVATEKEY_H
+
+#include "config.h"
+#include "DHPrivateKey.h"
+#include <botan/dh.h>
+#include <botan/version.h>
+
+// Derived from the DH_PrivateKey class
+class BotanDH_PrivateKey : public Botan::DH_PublicKey,
+ public virtual Botan::DL_Scheme_PrivateKey
+{
+public:
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> public_value() const;
+#else
+ Botan::MemoryVector<Botan::byte> public_value() const;
+#endif
+
+ // Constructors
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ BotanDH_PrivateKey(const Botan::AlgorithmIdentifier& alg_id,
+ const Botan::secure_vector<Botan::byte>& key_bits,
+ Botan::RandomNumberGenerator& rng);
+#else
+ BotanDH_PrivateKey(const Botan::AlgorithmIdentifier& alg_id,
+ const Botan::MemoryRegion<Botan::byte>& key_bits,
+ Botan::RandomNumberGenerator& rng);
+#endif
+
+ BotanDH_PrivateKey(Botan::RandomNumberGenerator& rng,
+ const Botan::DL_Group& grp,
+ const Botan::BigInt& x = 0);
+
+ ~BotanDH_PrivateKey();
+
+ Botan::DH_PrivateKey* impl;
+};
+
+class BotanDHPrivateKey : public DHPrivateKey
+{
+public:
+ // Constructors
+ BotanDHPrivateKey();
+
+ BotanDHPrivateKey(const BotanDH_PrivateKey* inDH);
+
+ // Destructor
+ virtual ~BotanDHPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DH private key components
+ virtual void setX(const ByteString& inX);
+
+ // Setters for the DH public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setG(const ByteString& inG);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const BotanDH_PrivateKey* inDH);
+
+ // Retrieve the Botan representation of the key
+ BotanDH_PrivateKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ BotanDH_PrivateKey* dh;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANDHPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDHPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanDHPublicKey.cpp
new file mode 100644
index 0000000..16c4b12
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDHPublicKey.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDHPublicKey.cpp
+
+ Botan Diffie-Hellman public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDHPublicKey.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanDHPublicKey::BotanDHPublicKey()
+{
+ dh = NULL;
+}
+
+BotanDHPublicKey::BotanDHPublicKey(const Botan::DH_PublicKey* inDH)
+{
+ dh = NULL;
+
+ setFromBotan(inDH);
+}
+
+// Destructor
+BotanDHPublicKey::~BotanDHPublicKey()
+{
+ delete dh;
+}
+
+// The type
+/*static*/ const char* BotanDHPublicKey::type = "Botan DH Public Key";
+
+// Set from Botan representation
+void BotanDHPublicKey::setFromBotan(const Botan::DH_PublicKey* inDH)
+{
+ ByteString inP = BotanUtil::bigInt2ByteString(inDH->group_p());
+ setP(inP);
+ ByteString inG = BotanUtil::bigInt2ByteString(inDH->group_g());
+ setG(inG);
+ ByteString inY = BotanUtil::bigInt2ByteString(inDH->get_y());
+ setY(inY);
+}
+
+// Check if the key is of the given type
+bool BotanDHPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DH public key components
+void BotanDHPublicKey::setP(const ByteString& inP)
+{
+ DHPublicKey::setP(inP);
+
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+}
+
+void BotanDHPublicKey::setG(const ByteString& inG)
+{
+ DHPublicKey::setG(inG);
+
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+}
+
+void BotanDHPublicKey::setY(const ByteString& inY)
+{
+ DHPublicKey::setY(inY);
+
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+}
+
+// Retrieve the Botan representation of the key
+Botan::DH_PublicKey* BotanDHPublicKey::getBotanKey()
+{
+ if (!dh)
+ {
+ createBotanKey();
+ }
+
+ return dh;
+}
+
+// Create the Botan representation of the key
+void BotanDHPublicKey::createBotanKey()
+{
+ // We actually do not need to check q, since it can be set zero
+ if (p.size() != 0 && y.size() != 0)
+ {
+ if (dh)
+ {
+ delete dh;
+ dh = NULL;
+ }
+
+ try
+ {
+ dh = new Botan::DH_PublicKey(Botan::DL_Group(BotanUtil::byteString2bigInt(p),
+ BotanUtil::byteString2bigInt(g)),
+ BotanUtil::byteString2bigInt(y));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanDHPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanDHPublicKey.h
new file mode 100644
index 0000000..66e90c2
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDHPublicKey.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDHPublicKey.h
+
+ Botan Diffie-Hellman public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDHPUBLICKEY_H
+#define _SOFTHSM_V2_BOTANDHPUBLICKEY_H
+
+#include "config.h"
+#include "DHPublicKey.h"
+#include <botan/dh.h>
+
+class BotanDHPublicKey : public DHPublicKey
+{
+public:
+ // Constructors
+ BotanDHPublicKey();
+
+ BotanDHPublicKey(const Botan::DH_PublicKey* inDH);
+
+ // Destructor
+ virtual ~BotanDHPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DH public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setG(const ByteString& inG);
+ virtual void setY(const ByteString& inY);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::DH_PublicKey* inDH);
+
+ // Retrieve the Botan representation of the key
+ Botan::DH_PublicKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::DH_PublicKey* dh;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANDHPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSA.cpp b/SoftHSMv2/src/lib/crypto/BotanDSA.cpp
new file mode 100644
index 0000000..ab3aa01
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSA.cpp
@@ -0,0 +1,760 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSA.cpp
+
+ Botan DSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDSA.h"
+#include "BotanRNG.h"
+#include "CryptoFactory.h"
+#include "BotanCryptoFactory.h"
+#include "DSAParameters.h"
+#include "BotanDSAKeyPair.h"
+#include "BotanUtil.h"
+#include <algorithm>
+#include <botan/dl_group.h>
+#include <botan/dsa.h>
+#include <botan/version.h>
+#include <iostream>
+
+// Constructor
+BotanDSA::BotanDSA()
+{
+ signer = NULL;
+ verifier = NULL;
+}
+
+// Destructor
+BotanDSA::~BotanDSA()
+{
+ delete signer;
+ delete verifier;
+}
+
+// Signing functions
+bool BotanDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ std::string emsa;
+
+ if (mechanism == AsymMech::DSA)
+ {
+ emsa = "Raw";
+ }
+ else
+ {
+ // Call default implementation
+ return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanDSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ BotanDSAPrivateKey* pk = (BotanDSAPrivateKey*) privateKey;
+ Botan::DSA_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ return false;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
+#else
+ signer = new Botan::PK_Signer(*botanKey, emsa);
+#endif
+ // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster.
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the signer token");
+
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not sign the data");
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete signer;
+ signer = NULL;
+
+ return true;
+}
+
+bool BotanDSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanDSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ std::string emsa;
+
+ switch (mechanism)
+ {
+ case AsymMech::DSA_SHA1:
+ emsa = "EMSA1(SHA-160)";
+ break;
+ case AsymMech::DSA_SHA224:
+ emsa = "EMSA1(SHA-224)";
+ break;
+ case AsymMech::DSA_SHA256:
+ emsa = "EMSA1(SHA-256)";
+ break;
+ case AsymMech::DSA_SHA384:
+ emsa = "EMSA1(SHA-384)";
+ break;
+ case AsymMech::DSA_SHA512:
+ emsa = "EMSA1(SHA-512)";
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ BotanDSAPrivateKey* pk = (BotanDSAPrivateKey*) currentPrivateKey;
+ Botan::DSA_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
+#else
+ signer = new Botan::PK_Signer(*botanKey, emsa);
+#endif
+ // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster.
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the signer token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanDSA::signUpdate(const ByteString& dataToSign)
+{
+ if (!AsymmetricAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (dataToSign.size() != 0)
+ {
+ signer->update(dataToSign.const_byte_str(),
+ dataToSign.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not add data to signer token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanDSA::signFinal(ByteString& signature)
+{
+ if (!AsymmetricAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signResult = signer->signature(*rng->getRNG());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not sign the data");
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete signer;
+ signer = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool BotanDSA::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ std::string emsa;
+
+ if (mechanism == AsymMech::DSA)
+ {
+ emsa = "Raw";
+ }
+ else
+ {
+ // Call the generic function
+ return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanDSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ BotanDSAPublicKey* pk = (BotanDSAPublicKey*) publicKey;
+ Botan::DSA_PublicKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ return false;
+ }
+
+ try
+ {
+ verifier = new Botan::PK_Verifier(*botanKey, emsa);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the verifier token");
+
+ return false;
+ }
+
+ // Perform the verify operation
+ bool verResult;
+ try
+ {
+ verResult = verifier->verify_message(originalData.const_byte_str(),
+ originalData.size(),
+ signature.const_byte_str(),
+ signature.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not check the signature");
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ delete verifier;
+ verifier = NULL;
+
+ return verResult;
+}
+
+bool BotanDSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanDSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ std::string emsa;
+
+ switch (mechanism)
+ {
+ case AsymMech::DSA_SHA1:
+ emsa = "EMSA1(SHA-160)";
+ break;
+ case AsymMech::DSA_SHA224:
+ emsa = "EMSA1(SHA-224)";
+ break;
+ case AsymMech::DSA_SHA256:
+ emsa = "EMSA1(SHA-256)";
+ break;
+ case AsymMech::DSA_SHA384:
+ emsa = "EMSA1(SHA-384)";
+ break;
+ case AsymMech::DSA_SHA512:
+ emsa = "EMSA1(SHA-512)";
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ BotanDSAPublicKey* pk = (BotanDSAPublicKey*) currentPublicKey;
+ Botan::DSA_PublicKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ try
+ {
+ verifier = new Botan::PK_Verifier(*botanKey, emsa);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the verifier token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanDSA::verifyUpdate(const ByteString& originalData)
+{
+ if (!AsymmetricAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (originalData.size() != 0)
+ {
+ verifier->update(originalData.const_byte_str(),
+ originalData.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not add data to the verifier token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanDSA::verifyFinal(const ByteString& signature)
+{
+ if (!AsymmetricAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the verify operation
+ bool verResult;
+ try
+ {
+ verResult = verifier->check_signature(signature.const_byte_str(), signature.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not check the signature");
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ delete verifier;
+ verifier = NULL;
+
+ return verResult;
+}
+
+// Encryption functions
+bool BotanDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DSA does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool BotanDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DSA does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool BotanDSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(DSAParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for DSA key generation");
+
+ return false;
+ }
+
+ DSAParameters* params = (DSAParameters*) parameters;
+
+ // Generate the key-pair
+ Botan::DSA_PrivateKey* dsa = NULL;
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ dsa = new Botan::DSA_PrivateKey(*rng->getRNG(),
+ Botan::DL_Group(BotanUtil::byteString2bigInt(params->getP()),
+ BotanUtil::byteString2bigInt(params->getQ()),
+ BotanUtil::byteString2bigInt(params->getG())));
+ }
+ catch (...)
+ {
+ ERROR_MSG("DSA key generation failed");
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ BotanDSAKeyPair* kp = new BotanDSAKeyPair();
+
+ ((BotanDSAPublicKey*) kp->getPublicKey())->setFromBotan(dsa);
+ ((BotanDSAPrivateKey*) kp->getPrivateKey())->setFromBotan(dsa);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ delete dsa;
+
+ return true;
+}
+
+unsigned long BotanDSA::getMinKeySize()
+{
+ return 512;
+}
+
+unsigned long BotanDSA::getMaxKeySize()
+{
+ // Taken from OpenSSL
+ return 10000;
+}
+
+bool BotanDSA::generateParameters(AsymmetricParameters** ppParams, void* parameters /* = NULL */, RNG* /*rng = NULL*/)
+{
+ if ((ppParams == NULL) || (parameters == NULL))
+ {
+ return false;
+ }
+
+ size_t bitLen = (size_t) parameters;
+
+ if (bitLen < getMinKeySize() || bitLen > getMaxKeySize())
+ {
+ ERROR_MSG("This DSA key size is not supported");
+
+ return false;
+ }
+
+ Botan::DL_Group* group = NULL;
+ // Taken from OpenSSL
+ size_t qLen = bitLen >= 2048 ? 256 : 160;
+ try
+ {
+ BotanRNG* brng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ group = new Botan::DL_Group(*brng->getRNG(), Botan::DL_Group::Prime_Subgroup, bitLen, qLen);
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Failed to generate %d bit DSA parameters: %s", bitLen, e.what());
+
+ return false;
+ }
+
+ // Store the DSA parameters
+ DSAParameters* params = new DSAParameters();
+
+ ByteString p = BotanUtil::bigInt2ByteString(group->get_p());
+ params->setP(p);
+ ByteString q = BotanUtil::bigInt2ByteString(group->get_q());
+ params->setQ(q);
+ ByteString g = BotanUtil::bigInt2ByteString(group->get_g());
+ params->setG(g);
+
+ *ppParams = params;
+
+ delete group;
+
+ return true;
+}
+
+bool BotanDSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ BotanDSAKeyPair* kp = new BotanDSAKeyPair();
+
+ bool rv = true;
+
+ if (!((DSAPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((DSAPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool BotanDSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanDSAPublicKey* pub = new BotanDSAPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool BotanDSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanDSAPrivateKey* priv = new BotanDSAPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* BotanDSA::newPublicKey()
+{
+ return (PublicKey*) new BotanDSAPublicKey();
+}
+
+PrivateKey* BotanDSA::newPrivateKey()
+{
+ return (PrivateKey*) new BotanDSAPrivateKey();
+}
+
+AsymmetricParameters* BotanDSA::newParameters()
+{
+ return (AsymmetricParameters*) new DSAParameters();
+}
+
+bool BotanDSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ DSAParameters* params = new DSAParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSA.h b/SoftHSMv2/src/lib/crypto/BotanDSA.h
new file mode 100644
index 0000000..dd10016
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSA.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSA.h
+
+ Botan DSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDSA_H
+#define _SOFTHSM_V2_BOTANDSA_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <botan/pubkey.h>
+
+class BotanDSA : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ BotanDSA();
+
+ // Destructor
+ virtual ~BotanDSA();
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool generateParameters(AsymmetricParameters** ppParams, void* parameters = NULL, RNG* rng = NULL);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ Botan::PK_Signer* signer;
+ Botan::PK_Verifier* verifier;
+};
+
+#endif // !_SOFTHSM_V2_BOTANDSA_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.cpp
new file mode 100644
index 0000000..9d98125
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSAKeyPair.cpp
+
+ Botan DSA key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDSAKeyPair.h"
+
+// Set the public key
+void BotanDSAKeyPair::setPublicKey(BotanDSAPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void BotanDSAKeyPair::setPrivateKey(BotanDSAPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* BotanDSAKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* BotanDSAKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* BotanDSAKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* BotanDSAKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.h
new file mode 100644
index 0000000..beb07e1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSAKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSAKeyPair.h
+
+ Botan DSA key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDSAKEYPAIR_H
+#define _SOFTHSM_V2_BOTANDSAKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "BotanDSAPublicKey.h"
+#include "BotanDSAPrivateKey.h"
+
+class BotanDSAKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(BotanDSAPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(BotanDSAPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ BotanDSAPublicKey pubKey;
+
+ // The private key
+ BotanDSAPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_BOTANDSAKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.cpp
new file mode 100644
index 0000000..a7f1c9b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.cpp
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSAPrivateKey.cpp
+
+ Botan DSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDSAPrivateKey.h"
+#include "BotanCryptoFactory.h"
+#include "BotanRNG.h"
+#include "BotanUtil.h"
+#include <string.h>
+#include <botan/pkcs8.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/oids.h>
+#include <botan/version.h>
+
+// Constructors
+BotanDSAPrivateKey::BotanDSAPrivateKey()
+{
+ dsa = NULL;
+}
+
+BotanDSAPrivateKey::BotanDSAPrivateKey(const Botan::DSA_PrivateKey* inDSA)
+{
+ dsa = NULL;
+
+ setFromBotan(inDSA);
+}
+
+// Destructor
+BotanDSAPrivateKey::~BotanDSAPrivateKey()
+{
+ delete dsa;
+}
+
+// The type
+/*static*/ const char* BotanDSAPrivateKey::type = "Botan DSA Private Key";
+
+// Set from Botan representation
+void BotanDSAPrivateKey::setFromBotan(const Botan::DSA_PrivateKey* inDSA)
+{
+ ByteString inP = BotanUtil::bigInt2ByteString(inDSA->group_p());
+ setP(inP);
+ ByteString inQ = BotanUtil::bigInt2ByteString(inDSA->group_q());
+ setQ(inQ);
+ ByteString inG = BotanUtil::bigInt2ByteString(inDSA->group_g());
+ setG(inG);
+ ByteString inX = BotanUtil::bigInt2ByteString(inDSA->get_x());
+ setX(inX);
+}
+
+// Check if the key is of the given type
+bool BotanDSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DSA private key components
+void BotanDSAPrivateKey::setX(const ByteString& inX)
+{
+ DSAPrivateKey::setX(inX);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+
+// Setters for the DSA domain parameters
+void BotanDSAPrivateKey::setP(const ByteString& inP)
+{
+ DSAPrivateKey::setP(inP);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+void BotanDSAPrivateKey::setQ(const ByteString& inQ)
+{
+ DSAPrivateKey::setQ(inQ);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+void BotanDSAPrivateKey::setG(const ByteString& inG)
+{
+ DSAPrivateKey::setG(inG);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString BotanDSAPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ createBotanKey();
+ if (dsa == NULL) return der;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ const Botan::secure_vector<Botan::byte> ber = Botan::PKCS8::BER_encode(*dsa);
+#else
+ const Botan::SecureVector<Botan::byte> ber = Botan::PKCS8::BER_encode(*dsa);
+#endif
+ der.resize(ber.size());
+ memcpy(&der[0], &ber[0], ber.size());
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool BotanDSAPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ Botan::DataSource_Memory source(ber.const_byte_str(), ber.size());
+ if (source.end_of_data()) return false;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> keydata;
+#else
+ Botan::SecureVector<Botan::byte> keydata;
+#endif
+ Botan::AlgorithmIdentifier alg_id;
+ Botan::DSA_PrivateKey* key = NULL;
+ try
+ {
+
+ Botan::BER_Decoder(source)
+ .start_cons(Botan::SEQUENCE)
+ .decode_and_check<size_t>(0, "Unknown PKCS #8 version number")
+ .decode(alg_id)
+ .decode(keydata, Botan::OCTET_STRING)
+ .discard_remaining()
+ .end_cons();
+ if (keydata.empty())
+ throw Botan::Decoding_Error("PKCS #8 private key decoding failed");
+ if (Botan::OIDS::lookup(alg_id.oid).compare("DSA"))
+ {
+ ERROR_MSG("Decoded private key not DSA");
+
+ return false;
+ }
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
+ key = new Botan::DSA_PrivateKey(alg_id, keydata);
+#else
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ key = new Botan::DSA_PrivateKey(alg_id, keydata, *rng->getRNG());
+#endif
+ if (key == NULL) return false;
+
+ setFromBotan(key);
+
+ delete key;
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Decode failed on %s", e.what());
+
+ return false;
+ }
+
+ return true;
+}
+
+// Retrieve the Botan representation of the key
+Botan::DSA_PrivateKey* BotanDSAPrivateKey::getBotanKey()
+{
+ if (!dsa)
+ {
+ createBotanKey();
+ }
+
+ return dsa;
+}
+
+// Create the Botan representation of the key
+void BotanDSAPrivateKey::createBotanKey()
+{
+ // y is not needed
+ // Todo: Either q or x is needed. Both is not needed
+ if (p.size() != 0 &&
+ q.size() != 0 &&
+ g.size() != 0 &&
+ x.size() != 0)
+ {
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ dsa = new Botan::DSA_PrivateKey(*rng->getRNG(),
+ Botan::DL_Group(BotanUtil::byteString2bigInt(p),
+ BotanUtil::byteString2bigInt(q),
+ BotanUtil::byteString2bigInt(g)),
+ BotanUtil::byteString2bigInt(x));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan private key");
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.h
new file mode 100644
index 0000000..5594967
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSAPrivateKey.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSAPrivateKey.h
+
+ Botan DSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDSAPRIVATEKEY_H
+#define _SOFTHSM_V2_BOTANDSAPRIVATEKEY_H
+
+#include "config.h"
+#include "DSAPrivateKey.h"
+#include <botan/dsa.h>
+
+class BotanDSAPrivateKey : public DSAPrivateKey
+{
+public:
+ // Constructors
+ BotanDSAPrivateKey();
+
+ BotanDSAPrivateKey(const Botan::DSA_PrivateKey* inDSA);
+
+ // Destructor
+ virtual ~BotanDSAPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DSA private key components
+ virtual void setX(const ByteString& inX);
+
+ // Setters for the DSA domain parameters
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setG(const ByteString& inG);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::DSA_PrivateKey* inDSA);
+
+ // Retrieve the Botan representation of the key
+ Botan::DSA_PrivateKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::DSA_PrivateKey* dsa;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANDSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.cpp
new file mode 100644
index 0000000..a1593d6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSAPublicKey.cpp
+
+ Botan DSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanDSAPublicKey.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanDSAPublicKey::BotanDSAPublicKey()
+{
+ dsa = NULL;
+}
+
+BotanDSAPublicKey::BotanDSAPublicKey(const Botan::DSA_PublicKey* inDSA)
+{
+ dsa = NULL;
+
+ setFromBotan(inDSA);
+}
+
+// Destructor
+BotanDSAPublicKey::~BotanDSAPublicKey()
+{
+ delete dsa;
+}
+
+// The type
+/*static*/ const char* BotanDSAPublicKey::type = "Botan DSA Public Key";
+
+// Set from Botan representation
+void BotanDSAPublicKey::setFromBotan(const Botan::DSA_PublicKey* inDSA)
+{
+ ByteString inP = BotanUtil::bigInt2ByteString(inDSA->group_p());
+ setP(inP);
+ ByteString inQ = BotanUtil::bigInt2ByteString(inDSA->group_q());
+ setQ(inQ);
+ ByteString inG = BotanUtil::bigInt2ByteString(inDSA->group_g());
+ setG(inG);
+ ByteString inY = BotanUtil::bigInt2ByteString(inDSA->get_y());
+ setY(inY);
+}
+
+// Check if the key is of the given type
+bool BotanDSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DSA public key components
+void BotanDSAPublicKey::setP(const ByteString& inP)
+{
+ DSAPublicKey::setP(inP);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+void BotanDSAPublicKey::setQ(const ByteString& inQ)
+{
+ DSAPublicKey::setQ(inQ);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+void BotanDSAPublicKey::setG(const ByteString& inG)
+{
+ DSAPublicKey::setG(inG);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+void BotanDSAPublicKey::setY(const ByteString& inY)
+{
+ DSAPublicKey::setY(inY);
+
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+}
+
+// Retrieve the Botan representation of the key
+Botan::DSA_PublicKey* BotanDSAPublicKey::getBotanKey()
+{
+ if (!dsa)
+ {
+ createBotanKey();
+ }
+
+ return dsa;
+}
+
+// Create the Botan representation of the key
+void BotanDSAPublicKey::createBotanKey()
+{
+ // We actually do not need to check q, since it can be set zero
+ if (p.size() != 0 &&
+ g.size() != 0 &&
+ y.size() != 0)
+ {
+ if (dsa)
+ {
+ delete dsa;
+ dsa = NULL;
+ }
+
+ try
+ {
+ dsa = new Botan::DSA_PublicKey(Botan::DL_Group(BotanUtil::byteString2bigInt(p),
+ BotanUtil::byteString2bigInt(q),
+ BotanUtil::byteString2bigInt(g)),
+ BotanUtil::byteString2bigInt(y));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.h
new file mode 100644
index 0000000..e4d683d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanDSAPublicKey.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanDSAPublicKey.h
+
+ Botan DSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANDSAPUBLICKEY_H
+#define _SOFTHSM_V2_BOTANDSAPUBLICKEY_H
+
+#include "config.h"
+#include "DSAPublicKey.h"
+#include <botan/dsa.h>
+
+class BotanDSAPublicKey : public DSAPublicKey
+{
+public:
+ // Constructors
+ BotanDSAPublicKey();
+
+ BotanDSAPublicKey(const Botan::DSA_PublicKey* inDSA);
+
+ // Destructor
+ virtual ~BotanDSAPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DSA public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setG(const ByteString& inG);
+ virtual void setY(const ByteString& inY);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::DSA_PublicKey* inDSA);
+
+ // Retrieve the Botan representation of the key
+ Botan::DSA_PublicKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::DSA_PublicKey* dsa;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANDSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDH.cpp b/SoftHSMv2/src/lib/crypto/BotanECDH.cpp
new file mode 100644
index 0000000..2741734
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDH.cpp
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDH.cpp
+
+ Botan ECDH asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDH.h"
+#include "BotanRNG.h"
+#include "CryptoFactory.h"
+#include "BotanCryptoFactory.h"
+#include "ECParameters.h"
+#include "BotanECDHKeyPair.h"
+#include "BotanUtil.h"
+#include <algorithm>
+#include <botan/dl_group.h>
+#include <botan/ecdh.h>
+#include <botan/pubkey.h>
+#include <botan/version.h>
+
+// Signing functions
+bool BotanECDH::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDH does not support signing");
+
+ return false;
+}
+
+bool BotanECDH::signUpdate(const ByteString& /*dataToSign*/)
+{
+ ERROR_MSG("ECDH does not support signing");
+
+ return false;
+}
+
+bool BotanECDH::signFinal(ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDH does not support signing");
+
+ return false;
+}
+
+// Verification functions
+bool BotanECDH::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDH does not support verifying");
+
+ return false;
+}
+
+bool BotanECDH::verifyUpdate(const ByteString& /*originalData*/)
+{
+ ERROR_MSG("ECDH does not support verifying");
+
+ return false;
+}
+
+bool BotanECDH::verifyFinal(const ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDH does not support verifying");
+
+ return false;
+}
+
+// Encryption functions
+bool BotanECDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDH does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool BotanECDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDH does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool BotanECDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(ECParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for ECDH key generation");
+
+ return false;
+ }
+
+ ECParameters* params = (ECParameters*) parameters;
+
+ // Generate the key-pair
+ Botan::ECDH_PrivateKey* eckp = NULL;
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ eckp = new Botan::ECDH_PrivateKey(*rng->getRNG(), BotanUtil::byteString2ECGroup(params->getEC()));
+ }
+ catch (...)
+ {
+ ERROR_MSG("ECDH key generation failed");
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ BotanECDHKeyPair* kp = new BotanECDHKeyPair();
+
+ ((BotanECDHPublicKey*) kp->getPublicKey())->setFromBotan(eckp);
+ ((BotanECDHPrivateKey*) kp->getPrivateKey())->setFromBotan(eckp);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ delete eckp;
+
+ return true;
+}
+
+bool BotanECDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
+{
+ // Check parameters
+ if ((ppSymmetricKey == NULL) ||
+ (publicKey == NULL) ||
+ (privateKey == NULL))
+ {
+ return false;
+ }
+
+ // Get keys
+ Botan::ECDH_PublicKey* pub = ((BotanECDHPublicKey*) publicKey)->getBotanKey();
+ Botan::ECDH_PrivateKey* priv = ((BotanECDHPrivateKey*) privateKey)->getBotanKey();
+ if (pub == NULL || priv == NULL)
+ {
+ ERROR_MSG("Failed to get Botan ECDH keys");
+
+ return false;
+ }
+
+ // Derive the secret
+ Botan::SymmetricKey sk;
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ Botan::PK_Key_Agreement ka(*priv, *rng->getRNG(), "Raw");
+#else
+ Botan::PK_Key_Agreement ka(*priv, "Raw");
+#endif
+ sk = ka.derive_key(0, pub->public_value());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Botan ECDH key agreement failed");
+
+ return false;
+ }
+
+ ByteString secret;
+
+ // We compensate that Botan removes leading zeros
+ int size = ((BotanECDHPublicKey *)publicKey)->getOrderLength();
+ int keySize = sk.length();
+ secret.wipe(size);
+ memcpy(&secret[0] + size - keySize, sk.begin(), keySize);
+
+ *ppSymmetricKey = new SymmetricKey(secret.size() * 8);
+ if (*ppSymmetricKey == NULL)
+ {
+ ERROR_MSG("Can't create ECDH secret");
+
+ return false;
+ }
+ if (!(*ppSymmetricKey)->setKeyBits(secret))
+ {
+ delete *ppSymmetricKey;
+ *ppSymmetricKey = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+unsigned long BotanECDH::getMinKeySize()
+{
+ // Smallest EC group is secp112r1
+ return 112;
+}
+
+unsigned long BotanECDH::getMaxKeySize()
+{
+ // Biggest EC group is secp521r1
+ return 521;
+}
+
+bool BotanECDH::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ BotanECDHKeyPair* kp = new BotanECDHKeyPair();
+
+ bool rv = true;
+
+ if (!((ECPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((ECPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool BotanECDH::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanECDHPublicKey* pub = new BotanECDHPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool BotanECDH::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanECDHPrivateKey* priv = new BotanECDHPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* BotanECDH::newPublicKey()
+{
+ return (PublicKey*) new BotanECDHPublicKey();
+}
+
+PrivateKey* BotanECDH::newPrivateKey()
+{
+ return (PrivateKey*) new BotanECDHPrivateKey();
+}
+
+AsymmetricParameters* BotanECDH::newParameters()
+{
+ return (AsymmetricParameters*) new ECParameters();
+}
+
+bool BotanECDH::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ECParameters* params = new ECParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDH.h b/SoftHSMv2/src/lib/crypto/BotanECDH.h
new file mode 100644
index 0000000..3fac507
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDH.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDH.h
+
+ Botan ECDH asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDH_H
+#define _SOFTHSM_V2_BOTANECDH_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <botan/pubkey.h>
+
+class BotanECDH : public AsymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~BotanECDH() { }
+
+ // Signing functions
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDH_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.cpp
new file mode 100644
index 0000000..74313d9
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDHKeyPair.cpp
+
+ Botan ECDH key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDHKeyPair.h"
+
+// Set the public key
+void BotanECDHKeyPair::setPublicKey(BotanECDHPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void BotanECDHKeyPair::setPrivateKey(BotanECDHPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* BotanECDHKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* BotanECDHKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* BotanECDHKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* BotanECDHKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.h
new file mode 100644
index 0000000..a9786b9
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDHKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDHKeyPair.h
+
+ Botan ECDH key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDHKEYPAIR_H
+#define _SOFTHSM_V2_BOTANECDHKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "BotanECDHPublicKey.h"
+#include "BotanECDHPrivateKey.h"
+
+class BotanECDHKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(BotanECDHPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(BotanECDHPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ BotanECDHPublicKey pubKey;
+
+ // The private key
+ BotanECDHPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDHKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.cpp
new file mode 100644
index 0000000..043e6e1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.cpp
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDHPrivateKey.cpp
+
+ Botan ECDH private key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDHPrivateKey.h"
+#include "BotanCryptoFactory.h"
+#include "BotanRNG.h"
+#include "BotanUtil.h"
+#include <string.h>
+#include <botan/pkcs8.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/asn1_oid.h>
+#include <botan/oids.h>
+#include <botan/version.h>
+
+// Constructors
+BotanECDHPrivateKey::BotanECDHPrivateKey()
+{
+ eckey = NULL;
+}
+
+BotanECDHPrivateKey::BotanECDHPrivateKey(const Botan::ECDH_PrivateKey* inECKEY)
+{
+ eckey = NULL;
+
+ setFromBotan(inECKEY);
+}
+
+// Destructor
+BotanECDHPrivateKey::~BotanECDHPrivateKey()
+{
+ delete eckey;
+}
+
+// The type
+/*static*/ const char* BotanECDHPrivateKey::type = "Botan ECDH Private Key";
+
+// Get the base point order length
+unsigned long BotanECDHPrivateKey::getOrderLength() const
+{
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ return group.get_order().bytes();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't get EC group for order length");
+
+ return 0;
+ }
+}
+
+// Set from Botan representation
+void BotanECDHPrivateKey::setFromBotan(const Botan::ECDH_PrivateKey* inECKEY)
+{
+ ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
+ setEC(inEC);
+ ByteString inD = BotanUtil::bigInt2ByteString(inECKEY->private_value());
+ setD(inD);
+}
+
+// Check if the key is of the given type
+bool BotanECDHPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the ECDH private key components
+void BotanECDHPrivateKey::setD(const ByteString& inD)
+{
+ ECPrivateKey::setD(inD);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Setters for the ECDH public key components
+void BotanECDHPrivateKey::setEC(const ByteString& inEC)
+{
+ ECPrivateKey::setEC(inEC);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString BotanECDHPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ createBotanKey();
+ if (eckey == NULL) return der;
+ const size_t PKCS8_VERSION = 0;
+ // No OID for ECDH
+ const Botan::OID oid("1.2.840.10045.2.1");
+ // Force EC_DOMPAR_ENC_OID
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+ const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
+ const Botan::AlgorithmIdentifier alg_id(oid, parameters);
+ const Botan::secure_vector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(eckey->private_key_bits(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
+ const Botan::AlgorithmIdentifier alg_id(oid, parameters);
+ const Botan::secure_vector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#else
+ const Botan::MemoryVector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
+ const Botan::AlgorithmIdentifier alg_id(oid, parameters);
+ const Botan::SecureVector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#endif
+ der.resize(ber.size());
+ memcpy(&der[0], &ber[0], ber.size());
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool BotanECDHPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ Botan::DataSource_Memory source(ber.const_byte_str(), ber.size());
+ if (source.end_of_data()) return false;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> keydata;
+#else
+ Botan::SecureVector<Botan::byte> keydata;
+#endif
+ Botan::AlgorithmIdentifier alg_id;
+ const Botan::OID oid("1.2.840.10045.2.1");
+ Botan::ECDH_PrivateKey* key = NULL;
+ try
+ {
+ Botan::BER_Decoder(source)
+ .start_cons(Botan::SEQUENCE)
+ .decode_and_check<size_t>(0, "Unknown PKCS #8 version number")
+ .decode(alg_id)
+ .decode(keydata, Botan::OCTET_STRING)
+ .discard_remaining()
+ .end_cons();
+ if (keydata.empty())
+ throw Botan::Decoding_Error("PKCS #8 private key decoding failed");
+ // Botan defines == but not != ?!
+ if (!(alg_id.oid == oid))
+ {
+ ERROR_MSG("Decoded private key not ECDH");
+
+ return false;
+ }
+ key = new Botan::ECDH_PrivateKey(alg_id, keydata);
+ if (key == NULL) return false;
+
+ setFromBotan(key);
+
+ delete key;
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Decode failed on %s", e.what());
+
+ return false;
+ }
+
+ return true;
+}
+
+// Retrieve the Botan representation of the key
+Botan::ECDH_PrivateKey* BotanECDHPrivateKey::getBotanKey()
+{
+ if (!eckey)
+ {
+ createBotanKey();
+ }
+
+ return eckey;
+}
+
+// Create the Botan representation of the key
+void BotanECDHPrivateKey::createBotanKey()
+{
+ if (ec.size() != 0 &&
+ d.size() != 0)
+ {
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ eckey = new Botan::ECDH_PrivateKey(*rng->getRNG(),
+ group,
+ BotanUtil::byteString2bigInt(d));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.h
new file mode 100644
index 0000000..d84e046
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDHPrivateKey.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDHPrivateKey.h
+
+ Botan ECDH private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDHPRIVATEKEY_H
+#define _SOFTHSM_V2_BOTANECDHPRIVATEKEY_H
+
+#include "config.h"
+#include "ECPrivateKey.h"
+#include <botan/ecdh.h>
+
+class BotanECDHPrivateKey : public ECPrivateKey
+{
+public:
+ // Constructors
+ BotanECDHPrivateKey();
+
+ BotanECDHPrivateKey(const Botan::ECDH_PrivateKey* inECKEY);
+
+ // Destructor
+ virtual ~BotanECDHPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the ECDH private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the ECDH public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::ECDH_PrivateKey* inECKEY);
+
+ // Retrieve the Botan representation of the key
+ Botan::ECDH_PrivateKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::ECDH_PrivateKey* eckey;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDHPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.cpp
new file mode 100644
index 0000000..6201f18
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDHPublicKey.cpp
+
+ Botan ECDH public key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDHPublicKey.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanECDHPublicKey::BotanECDHPublicKey()
+{
+ eckey = NULL;
+}
+
+BotanECDHPublicKey::BotanECDHPublicKey(const Botan::ECDH_PublicKey* inECKEY)
+{
+ eckey = NULL;
+
+ setFromBotan(inECKEY);
+}
+
+// Destructor
+BotanECDHPublicKey::~BotanECDHPublicKey()
+{
+ delete eckey;
+}
+
+// The type
+/*static*/ const char* BotanECDHPublicKey::type = "Botan ECDH Public Key";
+
+// Get the base point order length
+unsigned long BotanECDHPublicKey::getOrderLength() const
+{
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ return group.get_order().bytes();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't get EC group for order length");
+
+ return 0;
+ }
+}
+
+// Set from Botan representation
+void BotanECDHPublicKey::setFromBotan(const Botan::ECDH_PublicKey* inECKEY)
+{
+ ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
+ setEC(inEC);
+ ByteString inQ = BotanUtil::ecPoint2ByteString(inECKEY->public_point());
+ setQ(inQ);
+}
+
+// Check if the key is of the given type
+bool BotanECDHPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the ECDH public key components
+void BotanECDHPublicKey::setEC(const ByteString& inEC)
+{
+ ECPublicKey::setEC(inEC);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+void BotanECDHPublicKey::setQ(const ByteString& inQ)
+{
+ ECPublicKey::setQ(inQ);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Retrieve the Botan representation of the key
+Botan::ECDH_PublicKey* BotanECDHPublicKey::getBotanKey()
+{
+ if (!eckey)
+ {
+ createBotanKey();
+ }
+
+ return eckey;
+}
+
+// Create the Botan representation of the key
+void BotanECDHPublicKey::createBotanKey()
+{
+ if (ec.size() != 0 &&
+ q.size() != 0)
+ {
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ Botan::PointGFp point = BotanUtil::byteString2ECPoint(q, group);
+ eckey = new Botan::ECDH_PublicKey(group, point);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.h
new file mode 100644
index 0000000..0a10743
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDHPublicKey.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDHPublicKey.h
+
+ Botan ECDH public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDHPUBLICKEY_H
+#define _SOFTHSM_V2_BOTANECDHPUBLICKEY_H
+
+#include "config.h"
+#include "ECPublicKey.h"
+#include <botan/ecdh.h>
+
+class BotanECDHPublicKey : public ECPublicKey
+{
+public:
+ // Constructors
+ BotanECDHPublicKey();
+
+ BotanECDHPublicKey(const Botan::ECDH_PublicKey* inECKEY);
+
+ // Destructor
+ virtual ~BotanECDHPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the ECDH public key components
+ virtual void setEC(const ByteString& inEC);
+ virtual void setQ(const ByteString& inQ);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::ECDH_PublicKey* inECKEY);
+
+ // Retrieve the Botan representation of the key
+ Botan::ECDH_PublicKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::ECDH_PublicKey* eckey;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDHPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSA.cpp b/SoftHSMv2/src/lib/crypto/BotanECDSA.cpp
new file mode 100644
index 0000000..06b7a0f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSA.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSA.cpp
+
+ Botan ECDSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDSA.h"
+#include "BotanRNG.h"
+#include "CryptoFactory.h"
+#include "BotanCryptoFactory.h"
+#include "ECParameters.h"
+#include "BotanECDSAKeyPair.h"
+#include "BotanUtil.h"
+#include <algorithm>
+#include <botan/ec_group.h>
+#include <botan/ecdsa.h>
+#include <botan/version.h>
+#include <iostream>
+
+// Constructor
+BotanECDSA::BotanECDSA()
+{
+ signer = NULL;
+ verifier = NULL;
+}
+
+// Destructor
+BotanECDSA::~BotanECDSA()
+{
+ delete signer;
+ delete verifier;
+}
+
+// Signing functions
+bool BotanECDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ std::string emsa;
+
+ if (mechanism == AsymMech::ECDSA)
+ {
+ emsa = "Raw";
+ }
+ else
+ {
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanECDSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ BotanECDSAPrivateKey* pk = (BotanECDSAPrivateKey*) privateKey;
+ Botan::ECDSA_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (botanKey == NULL)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ return false;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
+#else
+ signer = new Botan::PK_Signer(*botanKey, emsa);
+#endif
+ // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster.
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the signer token");
+
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not sign the data");
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete signer;
+ signer = NULL;
+
+ return true;
+}
+
+// Signing functions
+bool BotanECDSA::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDSA does not support multi part signing");
+
+ return false;
+}
+
+bool BotanECDSA::signUpdate(const ByteString& /*dataToSign*/)
+{
+ ERROR_MSG("ECDSA does not support multi part signing");
+
+ return false;
+}
+
+bool BotanECDSA::signFinal(ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDSA does not support multi part signing");
+
+ return false;
+}
+
+// Verification functions
+bool BotanECDSA::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ std::string emsa;
+
+ if (mechanism == AsymMech::ECDSA)
+ {
+ emsa = "Raw";
+ }
+ else
+ {
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanECDSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ BotanECDSAPublicKey* pk = (BotanECDSAPublicKey*) publicKey;
+ Botan::ECDSA_PublicKey* botanKey = pk->getBotanKey();
+
+ if (botanKey == NULL)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ return false;
+ }
+
+ try
+ {
+ verifier = new Botan::PK_Verifier(*botanKey, emsa);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the verifier token");
+
+ return false;
+ }
+
+ // Perform the verify operation
+ bool verResult;
+ try
+ {
+ verResult = verifier->verify_message(originalData.const_byte_str(),
+ originalData.size(),
+ signature.const_byte_str(),
+ signature.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not check the signature");
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ delete verifier;
+ verifier = NULL;
+
+ return verResult;
+}
+
+// Verification functions
+bool BotanECDSA::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDSA does not support multi part verifying");
+
+ return false;
+}
+
+bool BotanECDSA::verifyUpdate(const ByteString& /*originalData*/)
+{
+ ERROR_MSG("ECDSA does not support multi part verifying");
+
+ return false;
+}
+
+bool BotanECDSA::verifyFinal(const ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDSA does not support multi part verifying");
+
+ return false;
+}
+
+// Encryption functions
+bool BotanECDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDSA does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool BotanECDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDSA does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool BotanECDSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(ECParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for ECDSA key generation");
+
+ return false;
+ }
+
+ ECParameters* params = (ECParameters*) parameters;
+
+ // Generate the key-pair
+ Botan::ECDSA_PrivateKey* eckp = NULL;
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ eckp = new Botan::ECDSA_PrivateKey(*rng->getRNG(), BotanUtil::byteString2ECGroup(params->getEC()));
+ }
+ catch (...)
+ {
+ ERROR_MSG("ECDSA key generation failed");
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ BotanECDSAKeyPair* kp = new BotanECDSAKeyPair();
+
+ ((BotanECDSAPublicKey*) kp->getPublicKey())->setFromBotan(eckp);
+ ((BotanECDSAPrivateKey*) kp->getPrivateKey())->setFromBotan(eckp);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ delete eckp;
+
+ return true;
+}
+
+unsigned long BotanECDSA::getMinKeySize()
+{
+ // Smallest EC group is secp112r1
+ return 112;
+}
+
+unsigned long BotanECDSA::getMaxKeySize()
+{
+ // Biggest EC group is secp521r1
+ return 521;
+}
+
+bool BotanECDSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ BotanECDSAKeyPair* kp = new BotanECDSAKeyPair();
+
+ bool rv = true;
+
+ if (!((ECPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((ECPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool BotanECDSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanECDSAPublicKey* pub = new BotanECDSAPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool BotanECDSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanECDSAPrivateKey* priv = new BotanECDSAPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* BotanECDSA::newPublicKey()
+{
+ return (PublicKey*) new BotanECDSAPublicKey();
+}
+
+PrivateKey* BotanECDSA::newPrivateKey()
+{
+ return (PrivateKey*) new BotanECDSAPrivateKey();
+}
+
+AsymmetricParameters* BotanECDSA::newParameters()
+{
+ return (AsymmetricParameters*) new ECParameters();
+}
+
+bool BotanECDSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ECParameters* params = new ECParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSA.h b/SoftHSMv2/src/lib/crypto/BotanECDSA.h
new file mode 100644
index 0000000..826d318
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSA.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSA.h
+
+ Botan ECDSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDSA_H
+#define _SOFTHSM_V2_BOTANECDSA_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <botan/pubkey.h>
+
+class BotanECDSA : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ BotanECDSA();
+
+ // Destructor
+ virtual ~BotanECDSA();
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ Botan::PK_Signer* signer;
+ Botan::PK_Verifier* verifier;
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDSA_H
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.cpp
new file mode 100644
index 0000000..ccc04d7
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSAKeyPair.cpp
+
+ Botan ECDSA key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDSAKeyPair.h"
+
+// Set the public key
+void BotanECDSAKeyPair::setPublicKey(BotanECDSAPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void BotanECDSAKeyPair::setPrivateKey(BotanECDSAPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* BotanECDSAKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* BotanECDSAKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* BotanECDSAKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* BotanECDSAKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.h
new file mode 100644
index 0000000..960923d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSAKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSAKeyPair.h
+
+ Botan ECDSA key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDSAKEYPAIR_H
+#define _SOFTHSM_V2_BOTANECDSAKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "BotanECDSAPublicKey.h"
+#include "BotanECDSAPrivateKey.h"
+
+class BotanECDSAKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(BotanECDSAPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(BotanECDSAPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ BotanECDSAPublicKey pubKey;
+
+ // The private key
+ BotanECDSAPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDSAKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.cpp
new file mode 100644
index 0000000..a276cb0
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSAPrivateKey.cpp
+
+ Botan ECDSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDSAPrivateKey.h"
+#include "BotanCryptoFactory.h"
+#include "BotanRNG.h"
+#include "BotanUtil.h"
+#include <string.h>
+#include <botan/pkcs8.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/asn1_oid.h>
+#include <botan/oids.h>
+#include <botan/version.h>
+
+// Constructors
+BotanECDSAPrivateKey::BotanECDSAPrivateKey()
+{
+ eckey = NULL;
+}
+
+BotanECDSAPrivateKey::BotanECDSAPrivateKey(const Botan::ECDSA_PrivateKey* inECKEY)
+{
+ eckey = NULL;
+
+ setFromBotan(inECKEY);
+}
+
+// Destructor
+BotanECDSAPrivateKey::~BotanECDSAPrivateKey()
+{
+ delete eckey;
+}
+
+// The type
+/*static*/ const char* BotanECDSAPrivateKey::type = "Botan ECDSA Private Key";
+
+// Get the base point order length
+unsigned long BotanECDSAPrivateKey::getOrderLength() const
+{
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ return group.get_order().bytes();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't get EC group for order length");
+
+ return 0;
+ }
+}
+
+// Set from Botan representation
+void BotanECDSAPrivateKey::setFromBotan(const Botan::ECDSA_PrivateKey* inECKEY)
+{
+ ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
+ setEC(inEC);
+ ByteString inD = BotanUtil::bigInt2ByteString(inECKEY->private_value());
+ setD(inD);
+}
+
+// Check if the key is of the given type
+bool BotanECDSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the ECDSA private key components
+void BotanECDSAPrivateKey::setD(const ByteString& inD)
+{
+ ECPrivateKey::setD(inD);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Setters for the ECDSA public key components
+void BotanECDSAPrivateKey::setEC(const ByteString& inEC)
+{
+ ECPrivateKey::setEC(inEC);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString BotanECDSAPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ createBotanKey();
+ if (eckey == NULL) return der;
+ // Force EC_DOMPAR_ENC_OID
+ const size_t PKCS8_VERSION = 0;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+ const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
+ const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
+ const Botan::secure_vector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(eckey->private_key_bits(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
+ const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
+ const Botan::secure_vector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#else
+ const Botan::MemoryVector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
+ const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
+ const Botan::SecureVector<Botan::byte> ber =
+ Botan::DER_Encoder()
+ .start_cons(Botan::SEQUENCE)
+ .encode(PKCS8_VERSION)
+ .encode(alg_id)
+ .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
+ .end_cons()
+ .get_contents();
+#endif
+ der.resize(ber.size());
+ memcpy(&der[0], &ber[0], ber.size());
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool BotanECDSAPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ Botan::DataSource_Memory source(ber.const_byte_str(), ber.size());
+ if (source.end_of_data()) return false;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> keydata;
+#else
+ Botan::SecureVector<Botan::byte> keydata;
+#endif
+ Botan::AlgorithmIdentifier alg_id;
+ Botan::ECDSA_PrivateKey* key = NULL;
+ try
+ {
+ Botan::BER_Decoder(source)
+ .start_cons(Botan::SEQUENCE)
+ .decode_and_check<size_t>(0, "Unknown PKCS #8 version number")
+ .decode(alg_id)
+ .decode(keydata, Botan::OCTET_STRING)
+ .discard_remaining()
+ .end_cons();
+ if (keydata.empty())
+ throw Botan::Decoding_Error("PKCS #8 private key decoding failed");
+ if (Botan::OIDS::lookup(alg_id.oid).compare("ECDSA"))
+ {
+ ERROR_MSG("Decoded private key not ECDSA");
+
+ return false;
+ }
+ key = new Botan::ECDSA_PrivateKey(alg_id, keydata);
+ if (key == NULL) return false;
+
+ setFromBotan(key);
+
+ delete key;
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Decode failed on %s", e.what());
+
+ return false;
+ }
+
+ return true;
+}
+
+// Retrieve the Botan representation of the key
+Botan::ECDSA_PrivateKey* BotanECDSAPrivateKey::getBotanKey()
+{
+ if (!eckey)
+ {
+ createBotanKey();
+ }
+
+ return eckey;
+}
+
+// Create the Botan representation of the key
+void BotanECDSAPrivateKey::createBotanKey()
+{
+ if (ec.size() != 0 &&
+ d.size() != 0)
+ {
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ eckey = new Botan::ECDSA_PrivateKey(*rng->getRNG(),
+ group,
+ BotanUtil::byteString2bigInt(d));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.h
new file mode 100644
index 0000000..4477442
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSAPrivateKey.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSAPrivateKey.h
+
+ Botan ECDSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDSAPRIVATEKEY_H
+#define _SOFTHSM_V2_BOTANECDSAPRIVATEKEY_H
+
+#include "config.h"
+#include "ECPrivateKey.h"
+#include <botan/ecdsa.h>
+
+class BotanECDSAPrivateKey : public ECPrivateKey
+{
+public:
+ // Constructors
+ BotanECDSAPrivateKey();
+
+ BotanECDSAPrivateKey(const Botan::ECDSA_PrivateKey* inECKEY);
+
+ // Destructor
+ virtual ~BotanECDSAPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the ECDSA private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the ECDSA public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::ECDSA_PrivateKey* inECKEY);
+
+ // Retrieve the Botan representation of the key
+ Botan::ECDSA_PrivateKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::ECDSA_PrivateKey* eckey;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.cpp
new file mode 100644
index 0000000..3409d88
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSAPublicKey.cpp
+
+ Botan ECDSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "BotanECDSAPublicKey.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanECDSAPublicKey::BotanECDSAPublicKey()
+{
+ eckey = NULL;
+}
+
+BotanECDSAPublicKey::BotanECDSAPublicKey(const Botan::ECDSA_PublicKey* inECKEY)
+{
+ eckey = NULL;
+
+ setFromBotan(inECKEY);
+}
+
+// Destructor
+BotanECDSAPublicKey::~BotanECDSAPublicKey()
+{
+ delete eckey;
+}
+
+// The type
+/*static*/ const char* BotanECDSAPublicKey::type = "Botan ECDSA Public Key";
+
+// Get the base point order length
+unsigned long BotanECDSAPublicKey::getOrderLength() const
+{
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ return group.get_order().bytes();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't get EC group for order length");
+
+ return 0;
+ }
+}
+
+// Set from Botan representation
+void BotanECDSAPublicKey::setFromBotan(const Botan::ECDSA_PublicKey* inECKEY)
+{
+ ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
+ setEC(inEC);
+ ByteString inQ = BotanUtil::ecPoint2ByteString(inECKEY->public_point());
+ setQ(inQ);
+}
+
+// Check if the key is of the given type
+bool BotanECDSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the ECDSA public key components
+void BotanECDSAPublicKey::setEC(const ByteString& inEC)
+{
+ ECPublicKey::setEC(inEC);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+void BotanECDSAPublicKey::setQ(const ByteString& inQ)
+{
+ ECPublicKey::setQ(inQ);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Retrieve the Botan representation of the key
+Botan::ECDSA_PublicKey* BotanECDSAPublicKey::getBotanKey()
+{
+ if (!eckey)
+ {
+ createBotanKey();
+ }
+
+ return eckey;
+}
+
+// Create the Botan representation of the key
+void BotanECDSAPublicKey::createBotanKey()
+{
+ if (ec.size() != 0 &&
+ q.size() != 0)
+ {
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ Botan::PointGFp point = BotanUtil::byteString2ECPoint(q, group);
+ eckey = new Botan::ECDSA_PublicKey(group, point);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.h
new file mode 100644
index 0000000..6ad0720
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanECDSAPublicKey.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanECDSAPublicKey.h
+
+ Botan ECDSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANECDSAPUBLICKEY_H
+#define _SOFTHSM_V2_BOTANECDSAPUBLICKEY_H
+
+#include "config.h"
+#include "ECPublicKey.h"
+#include <botan/ecdsa.h>
+
+class BotanECDSAPublicKey : public ECPublicKey
+{
+public:
+ // Constructors
+ BotanECDSAPublicKey();
+
+ BotanECDSAPublicKey(const Botan::ECDSA_PublicKey* inECKEY);
+
+ // Destructor
+ virtual ~BotanECDSAPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the ECDSA public key components
+ virtual void setEC(const ByteString& inEC);
+ virtual void setQ(const ByteString& inQ);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::ECDSA_PublicKey* inECKEY);
+
+ // Retrieve the Botan representation of the key
+ Botan::ECDSA_PublicKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::ECDSA_PublicKey* eckey;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANECDSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOST.cpp b/SoftHSMv2/src/lib/crypto/BotanGOST.cpp
new file mode 100644
index 0000000..ab02d54
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOST.cpp
@@ -0,0 +1,535 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOST.cpp
+
+ Botan GOST R 34.10-2001 asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "BotanGOST.h"
+#include "BotanRNG.h"
+#include "CryptoFactory.h"
+#include "BotanCryptoFactory.h"
+#include "ECParameters.h"
+#include "BotanGOSTKeyPair.h"
+#include "BotanUtil.h"
+#include <algorithm>
+#include <botan/ec_group.h>
+#include <botan/gost_3410.h>
+#include <botan/version.h>
+#include <iostream>
+
+// Constructor
+BotanGOST::BotanGOST()
+{
+ signer = NULL;
+ verifier = NULL;
+}
+
+// Destructor
+BotanGOST::~BotanGOST()
+{
+ delete signer;
+ delete verifier;
+}
+
+// Signing functions
+bool BotanGOST::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanGOSTPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ std::string emsa;
+
+ switch (mechanism)
+ {
+ case AsymMech::GOST:
+ emsa = "Raw";
+ break;
+ case AsymMech::GOST_GOST:
+ emsa = "EMSA1(GOST-34.11)";
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ BotanGOSTPrivateKey* pk = (BotanGOSTPrivateKey*) currentPrivateKey;
+ Botan::GOST_3410_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (botanKey == NULL)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
+#else
+ signer = new Botan::PK_Signer(*botanKey, emsa);
+#endif
+ // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster.
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the signer token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanGOST::signUpdate(const ByteString& dataToSign)
+{
+ if (!AsymmetricAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (dataToSign.size() != 0)
+ {
+ signer->update(dataToSign.const_byte_str(),
+ dataToSign.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not add data to signer token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanGOST::signFinal(ByteString& signature)
+{
+ if (!AsymmetricAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signResult = signer->signature(*rng->getRNG());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not sign the data");
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete signer;
+ signer = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool BotanGOST::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanGOSTPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ std::string emsa;
+
+ switch (mechanism)
+ {
+ case AsymMech::GOST:
+ emsa = "Raw";
+ break;
+ case AsymMech::GOST_GOST:
+ emsa = "EMSA1(GOST-34.11)";
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ BotanGOSTPublicKey* pk = (BotanGOSTPublicKey*) currentPublicKey;
+ Botan::GOST_3410_PublicKey* botanKey = pk->getBotanKey();
+
+ if (botanKey == NULL)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ try
+ {
+ verifier = new Botan::PK_Verifier(*botanKey, emsa);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the verifier token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanGOST::verifyUpdate(const ByteString& originalData)
+{
+ if (!AsymmetricAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (originalData.size() != 0)
+ {
+ verifier->update(originalData.const_byte_str(),
+ originalData.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not add data to the verifier token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanGOST::verifyFinal(const ByteString& signature)
+{
+ if (!AsymmetricAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the verify operation
+ bool verResult;
+ try
+ {
+ verResult = verifier->check_signature(signature.const_byte_str(), signature.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not check the signature");
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ delete verifier;
+ verifier = NULL;
+
+ return verResult;
+}
+
+// Encryption functions
+bool BotanGOST::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("GOST does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool BotanGOST::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("GOST does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool BotanGOST::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(ECParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for GOST key generation");
+
+ return false;
+ }
+
+ ECParameters* params = (ECParameters*) parameters;
+
+ // Generate the key-pair
+ Botan::GOST_3410_PrivateKey* eckp = NULL;
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ eckp = new Botan::GOST_3410_PrivateKey(*rng->getRNG(), BotanUtil::byteString2ECGroup(params->getEC()));
+ }
+ catch (...)
+ {
+ ERROR_MSG("GOST key generation failed");
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ BotanGOSTKeyPair* kp = new BotanGOSTKeyPair();
+
+ ((BotanGOSTPublicKey*) kp->getPublicKey())->setFromBotan(eckp);
+ ((BotanGOSTPrivateKey*) kp->getPrivateKey())->setFromBotan(eckp);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ delete eckp;
+
+ return true;
+}
+
+unsigned long BotanGOST::getMinKeySize()
+{
+ return 0;
+}
+
+unsigned long BotanGOST::getMaxKeySize()
+{
+ return 0;
+}
+
+bool BotanGOST::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ BotanGOSTKeyPair* kp = new BotanGOSTKeyPair();
+
+ bool rv = true;
+
+ if (!((BotanGOSTPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((BotanGOSTPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool BotanGOST::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanGOSTPublicKey* pub = new BotanGOSTPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool BotanGOST::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanGOSTPrivateKey* priv = new BotanGOSTPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* BotanGOST::newPublicKey()
+{
+ return (PublicKey*) new BotanGOSTPublicKey();
+}
+
+PrivateKey* BotanGOST::newPrivateKey()
+{
+ return (PrivateKey*) new BotanGOSTPrivateKey();
+}
+
+AsymmetricParameters* BotanGOST::newParameters()
+{
+ return (AsymmetricParameters*) new ECParameters();
+}
+
+bool BotanGOST::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ECParameters* params = new ECParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOST.h b/SoftHSMv2/src/lib/crypto/BotanGOST.h
new file mode 100644
index 0000000..a8085ab
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOST.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOST.h
+
+ Botan GOST R 34.10-2001 asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANGOST_H
+#define _SOFTHSM_V2_BOTANGOST_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <botan/pubkey.h>
+
+class BotanGOST : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ BotanGOST();
+
+ // Destructor
+ virtual ~BotanGOST();
+
+ // Signing functions
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ Botan::PK_Signer* signer;
+ Botan::PK_Verifier* verifier;
+};
+
+#endif // !_SOFTHSM_V2_BOTANGOST_H
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.cpp
new file mode 100644
index 0000000..08c3de5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTKeyPair.cpp
+
+ Botan GOST R 34.10-2001 key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "BotanGOSTKeyPair.h"
+
+// Set the public key
+void BotanGOSTKeyPair::setPublicKey(BotanGOSTPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void BotanGOSTKeyPair::setPrivateKey(BotanGOSTPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* BotanGOSTKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* BotanGOSTKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* BotanGOSTKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* BotanGOSTKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.h
new file mode 100644
index 0000000..2ff1b95
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTKeyPair.h
+
+ Botan GOST R 34.10-2001 key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANGOSTKEYPAIR_H
+#define _SOFTHSM_V2_BOTANGOSTKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "BotanGOSTPublicKey.h"
+#include "BotanGOSTPrivateKey.h"
+
+class BotanGOSTKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(BotanGOSTPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(BotanGOSTPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ BotanGOSTPublicKey pubKey;
+
+ // The private key
+ BotanGOSTPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_BOTANGOSTKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp
new file mode 100644
index 0000000..890f135
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTPrivateKey.cpp
+
+ Botan GOST R 34.10-2001 private key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "BotanGOSTPrivateKey.h"
+#include "BotanCryptoFactory.h"
+#include "BotanRNG.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanGOSTPrivateKey::BotanGOSTPrivateKey()
+{
+ eckey = NULL;
+}
+
+BotanGOSTPrivateKey::BotanGOSTPrivateKey(const Botan::GOST_3410_PrivateKey* inECKEY)
+{
+ BotanGOSTPrivateKey();
+
+ setFromBotan(inECKEY);
+}
+
+// Destructor
+BotanGOSTPrivateKey::~BotanGOSTPrivateKey()
+{
+ delete eckey;
+}
+
+// The type
+/*static*/ const char* BotanGOSTPrivateKey::type = "Botan GOST Private Key";
+
+// Get the base point order length
+unsigned long BotanGOSTPrivateKey::getOrderLength() const
+{
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ return group.get_order().bytes();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't get EC group for order length");
+
+ return 0;
+ }
+}
+
+// Get the output length
+unsigned long BotanGOSTPrivateKey::getOutputLength() const
+{
+ return getOrderLength() * 2;
+}
+
+// Set from Botan representation
+void BotanGOSTPrivateKey::setFromBotan(const Botan::GOST_3410_PrivateKey* inECKEY)
+{
+ ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
+ setEC(inEC);
+ ByteString inD = BotanUtil::bigInt2ByteStringPrefix(inECKEY->private_value(), 32);
+ setD(inD);
+}
+
+// Check if the key is of the given type
+bool BotanGOSTPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the GOST private key components
+void BotanGOSTPrivateKey::setD(const ByteString& inD)
+{
+ GOSTPrivateKey::setD(inD);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+
+// Setters for the GOST public key components
+void BotanGOSTPrivateKey::setEC(const ByteString& inEC)
+{
+ GOSTPrivateKey::setEC(inEC);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Serialisation
+ByteString BotanGOSTPrivateKey::serialise() const
+{
+ return ec.serialise() +
+ d.serialise();
+}
+
+bool BotanGOSTPrivateKey::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+ ByteString dD = ByteString::chainDeserialise(serialised);
+
+ if ((dEC.size() == 0) ||
+ (dD.size() == 0))
+ {
+ return false;
+ }
+
+ setEC(dEC);
+ setD(dD);
+
+ return true;
+}
+
+// Encode into PKCS#8 DER
+ByteString BotanGOSTPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ // TODO
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool BotanGOSTPrivateKey::PKCS8Decode(const ByteString& /*ber*/)
+{
+ return false;
+}
+
+// Retrieve the Botan representation of the key
+Botan::GOST_3410_PrivateKey* BotanGOSTPrivateKey::getBotanKey()
+{
+ if (!eckey)
+ {
+ createBotanKey();
+ }
+
+ return eckey;
+}
+
+// Create the Botan representation of the key
+void BotanGOSTPrivateKey::createBotanKey()
+{
+ if (ec.size() != 0 &&
+ d.size() != 0)
+ {
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ eckey = new Botan::GOST_3410_PrivateKey(*rng->getRNG(),
+ group,
+ BotanUtil::byteString2bigInt(d));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.h
new file mode 100644
index 0000000..cdc825b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTPrivateKey.h
+
+ Botan GOST R 34.10-2001 private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANGOSTPRIVATEKEY_H
+#define _SOFTHSM_V2_BOTANGOSTPRIVATEKEY_H
+
+#include "config.h"
+#include "GOSTPrivateKey.h"
+#include <botan/gost_3410.h>
+
+class BotanGOSTPrivateKey : public GOSTPrivateKey
+{
+public:
+ // Constructors
+ BotanGOSTPrivateKey();
+
+ BotanGOSTPrivateKey(const Botan::GOST_3410_PrivateKey* inECKEY);
+
+ // Destructor
+ virtual ~BotanGOSTPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the GOST private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the GOST public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::GOST_3410_PrivateKey* inECKEY);
+
+ // Retrieve the Botan representation of the key
+ Botan::GOST_3410_PrivateKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::GOST_3410_PrivateKey* eckey;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANGOSTPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.cpp
new file mode 100644
index 0000000..cebce66
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTPublicKey.cpp
+
+ Botan GOST R 34.10-2001 public key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "BotanGOSTPublicKey.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanGOSTPublicKey::BotanGOSTPublicKey()
+{
+ eckey = NULL;
+}
+
+BotanGOSTPublicKey::BotanGOSTPublicKey(const Botan::GOST_3410_PublicKey* inECKEY)
+{
+ BotanGOSTPublicKey();
+
+ setFromBotan(inECKEY);
+}
+
+// Destructor
+BotanGOSTPublicKey::~BotanGOSTPublicKey()
+{
+ delete eckey;
+}
+
+// The type
+/*static*/ const char* BotanGOSTPublicKey::type = "Botan GOST Public Key";
+
+// Get the base point order length
+unsigned long BotanGOSTPublicKey::getOrderLength() const
+{
+ try
+ {
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ return group.get_order().bytes();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't get EC group for order length");
+
+ return 0;
+ }
+}
+
+// Get the output length
+unsigned long BotanGOSTPublicKey::getOutputLength() const
+{
+ return getOrderLength() * 2;
+}
+
+// Set from Botan representation
+void BotanGOSTPublicKey::setFromBotan(const Botan::GOST_3410_PublicKey* inECKEY)
+{
+ ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
+ setEC(inEC);
+
+ ByteString inQ = BotanUtil::ecPoint2ByteString(inECKEY->public_point()).substr(3);
+
+ /* The points must be stored in little endian */
+ const size_t length = inQ.size() / 2;
+ for (size_t i = 0; i < (length / 2); i++)
+ {
+ std::swap(inQ[i], inQ[length-1-i]);
+ std::swap(inQ[length+i], inQ[2*length-1-i]);
+ }
+
+ setQ(inQ);
+}
+
+// Check if the key is of the given type
+bool BotanGOSTPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the GOST public key components
+void BotanGOSTPublicKey::setEC(const ByteString& inEC)
+{
+ GOSTPublicKey::setEC(inEC);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+void BotanGOSTPublicKey::setQ(const ByteString& inQ)
+{
+ GOSTPublicKey::setQ(inQ);
+
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+}
+
+// Serialisation
+ByteString BotanGOSTPublicKey::serialise() const
+{
+ return ec.serialise() +
+ q.serialise();
+}
+
+bool BotanGOSTPublicKey::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+
+ if ((dEC.size() == 0) ||
+ (dQ.size() == 0))
+ {
+ return false;
+ }
+
+ setEC(dEC);
+ setQ(dQ);
+
+ return true;
+}
+
+// Retrieve the Botan representation of the key
+Botan::GOST_3410_PublicKey* BotanGOSTPublicKey::getBotanKey()
+{
+ if (!eckey)
+ {
+ createBotanKey();
+ }
+
+ return eckey;
+}
+
+// Create the Botan representation of the key
+void BotanGOSTPublicKey::createBotanKey()
+{
+ if (ec.size() != 0 &&
+ q.size() != 0)
+ {
+ if (eckey)
+ {
+ delete eckey;
+ eckey = NULL;
+ }
+
+ try
+ {
+ /* The points are stored in little endian */
+ ByteString bPoint = q;
+ const size_t length = bPoint.size() / 2;
+ for (size_t i = 0; i < (length / 2); i++)
+ {
+ std::swap(bPoint[i], bPoint[length-1-i]);
+ std::swap(bPoint[length+i], bPoint[2*length-1-i]);
+ }
+ ByteString p = "044104" + bPoint;
+
+ Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
+ Botan::PointGFp point = BotanUtil::byteString2ECPoint(p, group);
+ eckey = new Botan::GOST_3410_PublicKey(group, point);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.h
new file mode 100644
index 0000000..6d7e8fc
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTPublicKey.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTPublicKey.h
+
+ Botan GOST R 34.11-2001 public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANGOSTPUBLICKEY_H
+#define _SOFTHSM_V2_BOTANGOSTPUBLICKEY_H
+
+#include "config.h"
+#include "GOSTPublicKey.h"
+#include <botan/gost_3410.h>
+
+class BotanGOSTPublicKey : public GOSTPublicKey
+{
+public:
+ // Constructors
+ BotanGOSTPublicKey();
+
+ BotanGOSTPublicKey(const Botan::GOST_3410_PublicKey* inECKEY);
+
+ // Destructor
+ virtual ~BotanGOSTPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the GOST public key components
+ virtual void setEC(const ByteString& inEC);
+ virtual void setQ(const ByteString& inQ);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::GOST_3410_PublicKey* inECKEY);
+
+ // Retrieve the Botan representation of the key
+ Botan::GOST_3410_PublicKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::GOST_3410_PublicKey* eckey;
+
+ // Create the Botan representation of the key
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANGOSTPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTR3411.cpp b/SoftHSMv2/src/lib/crypto/BotanGOSTR3411.cpp
new file mode 100644
index 0000000..344cdcd
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTR3411.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTR3411.cpp
+
+ Botan GOST R 34.11-94 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "BotanGOSTR3411.h"
+#include <botan/gost_3411.h>
+
+int BotanGOSTR3411::getHashSize()
+{
+ return 32;
+}
+
+Botan::HashFunction* BotanGOSTR3411::getHash() const
+{
+ return new Botan::GOST_34_11();
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTR3411.h b/SoftHSMv2/src/lib/crypto/BotanGOSTR3411.h
new file mode 100644
index 0000000..b0ee374
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanGOSTR3411.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanGOSTR3411.h
+
+ Botan GOST R 34.11-94 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANGOSTR3411_H
+#define _SOFTHSM_V2_BOTANGOSTR3411_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanGOSTR3411 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANGOSTR3411_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.cpp
new file mode 100644
index 0000000..9630dfc
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanHashAlgorithm.cpp
+
+ Base class for Botan hash algorithm classes
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/filters.h>
+
+// Base constructor
+BotanHashAlgorithm::BotanHashAlgorithm()
+{
+ hash = NULL;
+}
+
+// Destructor
+BotanHashAlgorithm::~BotanHashAlgorithm()
+{
+ delete hash;
+}
+
+// Hashing functions
+bool BotanHashAlgorithm::hashInit()
+{
+ if (!HashAlgorithm::hashInit())
+ {
+ return false;
+ }
+
+ // Initialize digesting
+ try
+ {
+ if (hash == NULL)
+ {
+ hash = getHash();
+ }
+ else
+ {
+ hash->clear();
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to initialize the digesting token");
+
+ ByteString dummy;
+ HashAlgorithm::hashFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanHashAlgorithm::hashUpdate(const ByteString& data)
+{
+ if (!HashAlgorithm::hashUpdate(data))
+ {
+ return false;
+ }
+
+ // Continue digesting
+ try
+ {
+ if (data.size() != 0)
+ {
+ hash->update(data.const_byte_str(), data.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to buffer data");
+
+ ByteString dummy;
+ HashAlgorithm::hashFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanHashAlgorithm::hashFinal(ByteString& hashedData)
+{
+ if (!HashAlgorithm::hashFinal(hashedData))
+ {
+ return false;
+ }
+
+ // Resize
+ hashedData.resize(hash->output_length());
+
+ // Read the digest
+ try
+ {
+ hash->final(&hashedData[0]);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to digest the data");
+
+ return false;
+ }
+
+ return true;
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.h b/SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.h
new file mode 100644
index 0000000..dde82db
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanHashAlgorithm.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanHashAlgorithm.h
+
+ Base class for Botan hash algorithm classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANHASHALGORITHM_H
+#define _SOFTHSM_V2_BOTANHASHALGORITHM_H
+
+#include "config.h"
+#include "HashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanHashAlgorithm : public HashAlgorithm
+{
+public:
+ // Base constructor
+ BotanHashAlgorithm();
+
+ // Destructor
+ virtual ~BotanHashAlgorithm();
+
+ // Hashing functions
+ virtual bool hashInit();
+ virtual bool hashUpdate(const ByteString& data);
+ virtual bool hashFinal(ByteString& hashedData);
+
+ virtual int getHashSize() = 0;
+protected:
+ virtual Botan::HashFunction* getHash() const = 0;
+
+private:
+ // Current hashing context
+ Botan::HashFunction *hash;
+};
+
+#endif // !_SOFTHSM_V2_BOTANHASHALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanMAC.cpp b/SoftHSMv2/src/lib/crypto/BotanMAC.cpp
new file mode 100644
index 0000000..b45f127
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanMAC.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanMAC.cpp
+
+ Botan MAC implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanMAC.h"
+
+std::string BotanHMACMD5::getAlgorithm() const
+{
+ return "HMAC(MD5)";
+}
+
+size_t BotanHMACMD5::getMacSize() const
+{
+ return 16;
+}
+
+std::string BotanHMACSHA1::getAlgorithm() const
+{
+ return "HMAC(SHA-1)";
+}
+
+size_t BotanHMACSHA1::getMacSize() const
+{
+ return 20;
+}
+
+std::string BotanHMACSHA224::getAlgorithm() const
+{
+ return "HMAC(SHA-224)";
+}
+
+size_t BotanHMACSHA224::getMacSize() const
+{
+ return 28;
+}
+
+std::string BotanHMACSHA256::getAlgorithm() const
+{
+ return "HMAC(SHA-256)";
+}
+
+size_t BotanHMACSHA256::getMacSize() const
+{
+ return 32;
+}
+
+std::string BotanHMACSHA384::getAlgorithm() const
+{
+ return "HMAC(SHA-384)";
+}
+
+size_t BotanHMACSHA384::getMacSize() const
+{
+ return 48;
+}
+
+std::string BotanHMACSHA512::getAlgorithm() const
+{
+ return "HMAC(SHA-512)";
+}
+
+size_t BotanHMACSHA512::getMacSize() const
+{
+ return 64;
+}
+
+#ifdef WITH_GOST
+std::string BotanHMACGOSTR3411::getAlgorithm() const
+{
+ return "HMAC(GOST-34.11)";
+}
+
+size_t BotanHMACGOSTR3411::getMacSize() const
+{
+ return 32;
+}
+#endif
+
+std::string BotanCMACDES::getAlgorithm() const
+{
+ switch(currentKey->getBitLen())
+ {
+ case 56:
+ ERROR_MSG("Only supporting 3DES");
+ return "";
+ case 112:
+ case 168:
+ return "CMAC(TripleDES)";
+ default:
+ break;
+ }
+
+ ERROR_MSG("Invalid DES bit len %i", currentKey->getBitLen());
+
+ return "";
+}
+
+size_t BotanCMACDES::getMacSize() const
+{
+ return 8;
+}
+
+std::string BotanCMACAES::getAlgorithm() const
+{
+ switch(currentKey->getBitLen())
+ {
+ case 128:
+ return "CMAC(AES-128)";
+ case 192:
+ return "CMAC(AES-192)";
+ case 256:
+ return "CMAC(AES-256)";
+ default:
+ break;
+ }
+
+ ERROR_MSG("Invalid AES bit len %i", currentKey->getBitLen());
+
+ return "";
+}
+
+size_t BotanCMACAES::getMacSize() const
+{
+ return 16;
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanMAC.h b/SoftHSMv2/src/lib/crypto/BotanMAC.h
new file mode 100644
index 0000000..4db9aee
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanMAC.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanMAC.h
+
+ Botan MAC implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANMAC_H
+#define _SOFTHSM_V2_BOTANMAC_H
+
+#include "config.h"
+#include "BotanMacAlgorithm.h"
+#include <botan/hmac.h>
+#include <botan/hash.h>
+
+class BotanHMACMD5 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+class BotanHMACSHA1 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+class BotanHMACSHA224 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+class BotanHMACSHA256 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+class BotanHMACSHA384 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+class BotanHMACSHA512 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+#ifdef WITH_GOST
+class BotanHMACGOSTR3411 : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+#endif
+
+class BotanCMACDES : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+class BotanCMACAES : public BotanMacAlgorithm
+{
+protected:
+ virtual std::string getAlgorithm() const;
+ virtual size_t getMacSize() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANMAC_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanMD5.cpp b/SoftHSMv2/src/lib/crypto/BotanMD5.cpp
new file mode 100644
index 0000000..382f53d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanMD5.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanMD5.cpp
+
+ Botan MD5 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanMD5.h"
+#include <botan/md5.h>
+
+int BotanMD5::getHashSize()
+{
+ return 16;
+}
+
+Botan::HashFunction* BotanMD5::getHash() const
+{
+ return new Botan::MD5();
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanMD5.h b/SoftHSMv2/src/lib/crypto/BotanMD5.h
new file mode 100644
index 0000000..6542019
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanMD5.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanMD5.h
+
+ Botan MD5 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANMD5_H
+#define _SOFTHSM_V2_BOTANMD5_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanMD5 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANMD5_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.cpp
new file mode 100644
index 0000000..6c863f7
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.cpp
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// TODO: Store context in securely allocated memory
+
+/*****************************************************************************
+ BotanMacAlgorithm.cpp
+
+ Botan MAC algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanMacAlgorithm.h"
+#include "salloc.h"
+
+#include <botan/symkey.h>
+#include <botan/mac.h>
+#include <botan/botan.h>
+#include <botan/version.h>
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,26)
+#include <botan/lookup.h>
+#endif
+
+// Constructor
+BotanMacAlgorithm::BotanMacAlgorithm()
+{
+ mac = NULL;
+}
+
+// Destructor
+BotanMacAlgorithm::~BotanMacAlgorithm()
+{
+ delete mac;
+ mac = NULL;
+}
+
+// Signing functions
+bool BotanMacAlgorithm::signInit(const SymmetricKey* key)
+{
+ // Call the superclass initialiser
+ if (!MacAlgorithm::signInit(key))
+ {
+ return false;
+ }
+
+ // Determine the hash name
+ std::string macName = getAlgorithm();
+
+ if (macName == "")
+ {
+ ERROR_MSG("Invalid sign mac algorithm");
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ // Allocate the context
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,26)
+ mac = Botan::MessageAuthenticationCode::create(macName).release();
+#else
+ mac = Botan::get_mac(macName);
+#endif
+ mac->set_key(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+ }
+ catch (std::exception &e)
+ {
+ ERROR_MSG("Failed to create the sign mac token: %s", e.what());
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanMacAlgorithm::signUpdate(const ByteString& dataToSign)
+{
+ if (!MacAlgorithm::signUpdate(dataToSign))
+ {
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ try
+ {
+ if (dataToSign.size() != 0)
+ {
+ mac->update(dataToSign.const_byte_str(),
+ dataToSign.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to update the sign mac token");
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanMacAlgorithm::signFinal(ByteString& signature)
+{
+ if (!MacAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ signResult = mac->final();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not sign the data");
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete mac;
+ mac = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool BotanMacAlgorithm::verifyInit(const SymmetricKey* key)
+{
+ // Call the superclass initialiser
+ if (!MacAlgorithm::verifyInit(key))
+ {
+ return false;
+ }
+
+ // Determine the hash name
+ std::string macName = getAlgorithm();
+
+ if (macName == "")
+ {
+ ERROR_MSG("Invalid verify mac algorithm");
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ // Allocate the context
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,26)
+ mac = Botan::MessageAuthenticationCode::create(macName).release();
+#else
+ mac = Botan::get_mac(macName);
+#endif
+ mac->set_key(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+ }
+ catch (std::exception &e)
+ {
+ ERROR_MSG("Failed to create the verify mac token: %s", e.what());
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanMacAlgorithm::verifyUpdate(const ByteString& originalData)
+{
+ if (!MacAlgorithm::verifyUpdate(originalData))
+ {
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ try
+ {
+ if (originalData.size() != 0)
+ {
+ mac->update(originalData.const_byte_str(),
+ originalData.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to update the verify mac token");
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanMacAlgorithm::verifyFinal(ByteString& signature)
+{
+ if (!MacAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the verify operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> macResult;
+#else
+ Botan::SecureVector<Botan::byte> macResult;
+#endif
+ try
+ {
+ macResult = mac->final();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to verify the data");
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ if (macResult.size() != signature.size())
+ {
+ ERROR_MSG("Bad verify result size");
+
+ delete mac;
+ mac = NULL;
+
+ return false;
+ }
+
+ delete mac;
+ mac = NULL;
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ return memcmp(&signature[0], macResult.data(), macResult.size()) == 0;
+#else
+ return memcmp(&signature[0], macResult.begin(), macResult.size()) == 0;
+#endif
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.h b/SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.h
new file mode 100644
index 0000000..ac71009
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanMacAlgorithm.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanMacAlgorithm.h
+
+ Botan MAC algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANMACALGORITHM_H
+#define _SOFTHSM_V2_BOTANMACALGORITHM_H
+
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "MacAlgorithm.h"
+#include <botan/mac.h>
+
+class BotanMacAlgorithm : public MacAlgorithm
+{
+public:
+ // Constructor
+ BotanMacAlgorithm();
+
+ // Destructor
+ virtual ~BotanMacAlgorithm();
+
+ // Signing functions
+ virtual bool signInit(const SymmetricKey* key);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(const SymmetricKey* key);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(ByteString& signature);
+
+ // Return the MAC size
+ virtual size_t getMacSize() const = 0;
+
+protected:
+ // Return the right algorithm for the operation
+ virtual std::string getAlgorithm() const = 0;
+
+private:
+ // The current context
+ Botan::MessageAuthenticationCode* mac;
+};
+
+#endif // !_SOFTHSM_V2_BOTANMACALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanRNG.cpp b/SoftHSMv2/src/lib/crypto/BotanRNG.cpp
new file mode 100644
index 0000000..fa6509d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRNG.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BOTANRNG.cpp
+
+ Botan random number generator class
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanRNG.h"
+
+#include <botan/version.h>
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+#include <botan/libstate.h>
+#else
+#include <botan/auto_rng.h>
+#endif
+
+// Base constructor
+BotanRNG::BotanRNG()
+{
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,14)
+ rng = &Botan::global_state().global_rng();
+#else
+ rng = new Botan::AutoSeeded_RNG();
+#endif
+}
+
+// Destructor
+BotanRNG::~BotanRNG()
+{
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,14)
+ delete rng;
+#endif
+}
+
+// Generate random data
+bool BotanRNG::generateRandom(ByteString& data, const size_t len)
+{
+ data.wipe(len);
+
+ if (len > 0)
+ rng->randomize(&data[0], len);
+
+ return true;
+}
+
+// Seed the random pool
+void BotanRNG::seed(ByteString& seedData)
+{
+ rng->add_entropy(seedData.byte_str(), seedData.size());
+ // add_entropy will make sure the RNG is reseed so we do not need to call it.
+ // Made this change bacuase of API changes in Botan 1.11.31,
+ // but the statement above is also true for Botan 1.10.
+ // rng->reseed(seedData.size());
+}
+
+// Get the RNG
+Botan::RandomNumberGenerator* BotanRNG::getRNG()
+{
+ return rng;
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanRNG.h b/SoftHSMv2/src/lib/crypto/BotanRNG.h
new file mode 100644
index 0000000..f14b22e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRNG.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRNG.h
+
+ Botan random number generator class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANRNG_H
+#define _SOFTHSM_V2_BOTANRNG_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "RNG.h"
+
+#include "botan/rng.h"
+
+class BotanRNG : public RNG
+{
+public:
+ // Base constructor
+ BotanRNG();
+
+ // Destructor
+ virtual ~BotanRNG();
+
+ // Generate random data
+ virtual bool generateRandom(ByteString& data, const size_t len);
+
+ // Seed the random pool
+ virtual void seed(ByteString& seedData);
+
+ // Get RNG
+ Botan::RandomNumberGenerator* getRNG();
+
+private:
+ // The RNG
+ Botan::RandomNumberGenerator* rng;
+};
+
+#endif // !_SOFTHSM_V2_BOTANRNG_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSA.cpp b/SoftHSMv2/src/lib/crypto/BotanRSA.cpp
new file mode 100644
index 0000000..2fbb4e2
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSA.cpp
@@ -0,0 +1,1219 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSA.cpp
+
+ Botan RSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanRSA.h"
+#include "BotanRNG.h"
+#include "CryptoFactory.h"
+#include "BotanCryptoFactory.h"
+#include "RSAParameters.h"
+#include "BotanRSAKeyPair.h"
+#include <algorithm>
+#include <botan/rsa.h>
+#include <botan/version.h>
+#include <sstream>
+
+// Constructor
+BotanRSA::BotanRSA()
+{
+ signer = NULL;
+ verifier = NULL;
+}
+
+// Destructor
+BotanRSA::~BotanRSA()
+{
+ delete signer;
+ delete verifier;
+}
+
+// Signing functions
+bool BotanRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ std::string emsa = "";
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA:
+ emsa = "Raw";
+ break;
+ case AsymMech::RSA_PKCS:
+ emsa = "EMSA3(Raw)";
+ break;
+#ifdef WITH_RAW_PSS
+ case AsymMech::RSA_PKCS_PSS:
+ emsa = getCipherRawPss(privateKey->getBitLength(), dataToSign.size(), param, paramLen);
+ if (emsa == "")
+ {
+ return false;
+ }
+ break;
+#endif
+ default:
+ // Call default implementation
+ return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey;
+ Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ return false;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
+#else
+ signer = new Botan::PK_Signer(*botanKey, emsa);
+#endif
+ // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster.
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the signer token");
+
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signResult = signer->sign_message(dataToSign.const_byte_str(), dataToSign.size(), *rng->getRNG());
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Could not sign the data: %s", e.what());
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete signer;
+ signer = NULL;
+
+ return true;
+}
+
+bool BotanRSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ std::string emsa;
+ std::ostringstream request;
+ size_t sLen;
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA_MD5_PKCS:
+ emsa = "EMSA3(MD5)";
+ break;
+ case AsymMech::RSA_SHA1_PKCS:
+ emsa = "EMSA3(SHA-160)";
+ break;
+ case AsymMech::RSA_SHA224_PKCS:
+ emsa = "EMSA3(SHA-224)";
+ break;
+ case AsymMech::RSA_SHA256_PKCS:
+ emsa = "EMSA3(SHA-256)";
+ break;
+ case AsymMech::RSA_SHA384_PKCS:
+ emsa = "EMSA3(SHA-384)";
+ break;
+ case AsymMech::RSA_SHA512_PKCS:
+ emsa = "EMSA3(SHA-512)";
+ break;
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-20))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-160,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-28))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-224,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-32))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-256,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-48))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-384,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-64))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-512,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SSL:
+ emsa = "EMSA3(Parallel(MD5,SHA-160))";
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) currentPrivateKey;
+ Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signer = new Botan::PK_Signer(*botanKey, *rng->getRNG(), emsa);
+#else
+ signer = new Botan::PK_Signer(*botanKey, emsa);
+#endif
+ // Should we add DISABLE_FAULT_PROTECTION? Makes this operation faster.
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the signer token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanRSA::signUpdate(const ByteString& dataToSign)
+{
+ if (!AsymmetricAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (dataToSign.size() != 0)
+ {
+ signer->update(dataToSign.const_byte_str(),
+ dataToSign.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not add data to signer token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanRSA::signFinal(ByteString& signature)
+{
+ if (!AsymmetricAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the signature operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> signResult;
+#else
+ Botan::SecureVector<Botan::byte> signResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ signResult = signer->signature(*rng->getRNG());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not sign the data");
+
+ delete signer;
+ signer = NULL;
+
+ return false;
+ }
+
+ // Return the result
+ signature.resize(signResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&signature[0], signResult.data(), signResult.size());
+#else
+ memcpy(&signature[0], signResult.begin(), signResult.size());
+#endif
+
+ delete signer;
+ signer = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool BotanRSA::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ std::string emsa = "";
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA:
+ emsa = "Raw";
+ break;
+ case AsymMech::RSA_PKCS:
+ emsa = "EMSA3(Raw)";
+ break;
+#ifdef WITH_RAW_PSS
+ case AsymMech::RSA_PKCS_PSS:
+ emsa = getCipherRawPss(publicKey->getBitLength(), originalData.size(), param, paramLen);
+ if (emsa == "")
+ {
+ return false;
+ }
+ break;
+#endif
+ default:
+ // Call the generic function
+ return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
+ Botan::RSA_PublicKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ return false;
+ }
+
+ try
+ {
+ verifier = new Botan::PK_Verifier(*botanKey, emsa);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the verifier token");
+
+ return false;
+ }
+
+ // Perform the verify operation
+ bool verResult;
+ try
+ {
+ verResult = verifier->verify_message(originalData.const_byte_str(),
+ originalData.size(),
+ signature.const_byte_str(),
+ signature.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not check the signature");
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ delete verifier;
+ verifier = NULL;
+
+ return verResult;
+}
+
+bool BotanRSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ std::string emsa;
+ std::ostringstream request;
+ size_t sLen;
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA_MD5_PKCS:
+ emsa = "EMSA3(MD5)";
+ break;
+ case AsymMech::RSA_SHA1_PKCS:
+ emsa = "EMSA3(SHA-160)";
+ break;
+ case AsymMech::RSA_SHA224_PKCS:
+ emsa = "EMSA3(SHA-224)";
+ break;
+ case AsymMech::RSA_SHA256_PKCS:
+ emsa = "EMSA3(SHA-256)";
+ break;
+ case AsymMech::RSA_SHA384_PKCS:
+ emsa = "EMSA3(SHA-384)";
+ break;
+ case AsymMech::RSA_SHA512_PKCS:
+ emsa = "EMSA3(SHA-512)";
+ break;
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-20))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-160,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-28))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-224,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-32))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-256,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-48))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-384,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-64))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ request << "EMSA4(SHA-512,MGF1," << sLen << ")";
+ emsa = request.str();
+ break;
+ case AsymMech::RSA_SSL:
+ emsa = "EMSA3(Parallel(MD5,SHA-160))";
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ BotanRSAPublicKey* pk = (BotanRSAPublicKey*) currentPublicKey;
+ Botan::RSA_PublicKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ try
+ {
+ verifier = new Botan::PK_Verifier(*botanKey, emsa);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the verifier token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanRSA::verifyUpdate(const ByteString& originalData)
+{
+ if (!AsymmetricAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ try
+ {
+ if (originalData.size() != 0)
+ {
+ verifier->update(originalData.const_byte_str(),
+ originalData.size());
+ }
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not add data to the verifier token");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanRSA::verifyFinal(const ByteString& signature)
+{
+ if (!AsymmetricAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the verify operation
+ bool verResult;
+ try
+ {
+ verResult = verifier->check_signature(signature.const_byte_str(), signature.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not check the signature");
+
+ delete verifier;
+ verifier = NULL;
+
+ return false;
+ }
+
+ delete verifier;
+ verifier = NULL;
+
+ return verResult;
+}
+
+// Encryption functions
+bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data,
+ ByteString& encryptedData, const AsymMech::Type padding)
+{
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(BotanRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ std::string eme;
+
+ switch (padding)
+ {
+ case AsymMech::RSA_PKCS:
+ eme = "PKCS1v15";
+ break;
+ case AsymMech::RSA_PKCS_OAEP:
+ eme = "EME1(SHA-160)";
+ break;
+ case AsymMech::RSA:
+ eme = "Raw";
+ break;
+ default:
+ ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
+
+ return false;
+ }
+
+ BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
+ Botan::RSA_PublicKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan public key");
+
+ return false;
+ }
+
+ Botan::PK_Encryptor_EME* encryptor = NULL;
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ encryptor = new Botan::PK_Encryptor_EME(*botanKey, *rng->getRNG(), eme);
+#else
+ encryptor = new Botan::PK_Encryptor_EME(*botanKey, eme);
+#endif
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the encryptor token");
+
+ return false;
+ }
+
+ // Perform the encryption operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> encResult;
+#else
+ Botan::SecureVector<Botan::byte> encResult;
+#endif
+ try
+ {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ encResult = encryptor->encrypt(data.const_byte_str(), data.size(), *rng->getRNG());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not encrypt the data");
+
+ delete encryptor;
+
+ return false;
+ }
+
+ // Return the result
+ encryptedData.resize(encResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&encryptedData[0], encResult.data(), encResult.size());
+#else
+ memcpy(&encryptedData[0], encResult.begin(), encResult.size());
+#endif
+
+ delete encryptor;
+
+ return true;
+}
+
+// Decryption functions
+bool BotanRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData,
+ ByteString& data, const AsymMech::Type padding)
+{
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(BotanRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ std::string eme;
+
+ switch (padding)
+ {
+ case AsymMech::RSA_PKCS:
+ eme = "PKCS1v15";
+ break;
+ case AsymMech::RSA_PKCS_OAEP:
+ eme = "EME1(SHA-160)";
+ break;
+ case AsymMech::RSA:
+ eme = "Raw";
+ break;
+ default:
+ ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
+
+ return false;
+ }
+
+ BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey;
+ Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();
+
+ if (!botanKey)
+ {
+ ERROR_MSG("Could not get the Botan private key");
+
+ return false;
+ }
+
+ Botan::PK_Decryptor_EME* decryptor = NULL;
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,33)
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ decryptor = new Botan::PK_Decryptor_EME(*botanKey, *rng->getRNG(), eme);
+#else
+ decryptor = new Botan::PK_Decryptor_EME(*botanKey, eme);
+#endif
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the decryptor token");
+
+ return false;
+ }
+
+ // Perform the decryption operation
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> decResult;
+#else
+ Botan::SecureVector<Botan::byte> decResult;
+#endif
+ try
+ {
+ decResult = decryptor->decrypt(encryptedData.const_byte_str(), encryptedData.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not decrypt the data");
+
+ delete decryptor;
+
+ return false;
+ }
+
+ // Return the result
+ if (padding == AsymMech::RSA)
+ {
+ // We compensate that Botan removes leading zeros
+ int modSize = pk->getN().size();
+ int decSize = decResult.size();
+ data.resize(modSize);
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&data[0] + modSize - decSize, decResult.data(), decSize);
+#else
+ memcpy(&data[0] + modSize - decSize, decResult.begin(), decSize);
+#endif
+ }
+ else
+ {
+ data.resize(decResult.size());
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ memcpy(&data[0], decResult.data(), decResult.size());
+#else
+ memcpy(&data[0], decResult.begin(), decResult.size());
+#endif
+ }
+
+ delete decryptor;
+
+ return true;
+}
+
+// Key factory
+bool BotanRSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(RSAParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for RSA key generation");
+
+ return false;
+ }
+
+ RSAParameters* params = (RSAParameters*) parameters;
+
+ if (params->getBitLength() < getMinKeySize() || params->getBitLength() > getMaxKeySize())
+ {
+ ERROR_MSG("This RSA key size (%lu) is not supported", params->getBitLength());
+
+ return false;
+ }
+
+ // Retrieve the desired public exponent
+ unsigned long e = params->getE().long_val();
+
+ // Check the public exponent
+ if ((e == 0) || (e % 2 != 1))
+ {
+ ERROR_MSG("Invalid RSA public exponent %d", e);
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ BotanRSAKeyPair* kp = new BotanRSAKeyPair();
+
+ // Generate the key-pair
+ Botan::RSA_PrivateKey* rsa = NULL;
+ try {
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ rsa = new Botan::RSA_PrivateKey(*rng->getRNG(), params->getBitLength(), e);
+ }
+ catch (std::exception& ex) {
+ ERROR_MSG("RSA key generation failed: %s", ex.what());
+
+ delete kp;
+
+ return false;
+ }
+
+ ((BotanRSAPublicKey*) kp->getPublicKey())->setFromBotan(rsa);
+ ((BotanRSAPrivateKey*) kp->getPrivateKey())->setFromBotan(rsa);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ delete rsa;
+
+ return true;
+}
+
+unsigned long BotanRSA::getMinKeySize()
+{
+ return 1024;
+}
+
+unsigned long BotanRSA::getMaxKeySize()
+{
+ return 4096;
+}
+
+bool BotanRSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ BotanRSAKeyPair* kp = new BotanRSAKeyPair();
+
+ bool rv = true;
+
+ if (!((RSAPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((RSAPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool BotanRSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanRSAPublicKey* pub = new BotanRSAPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool BotanRSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ BotanRSAPrivateKey* priv = new BotanRSAPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* BotanRSA::newPublicKey()
+{
+ return (PublicKey*) new BotanRSAPublicKey();
+}
+
+PrivateKey* BotanRSA::newPrivateKey()
+{
+ return (PrivateKey*) new BotanRSAPrivateKey();
+}
+
+AsymmetricParameters* BotanRSA::newParameters()
+{
+ return (AsymmetricParameters*) new RSAParameters();
+}
+
+bool BotanRSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ RSAParameters* params = new RSAParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+
+#ifdef WITH_RAW_PSS
+std::string BotanRSA::getCipherRawPss(size_t bitLength, size_t dataSize, const void* param, const size_t paramLen)
+{
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS))
+ {
+ ERROR_MSG("Invalid parameters");
+ return "";
+ }
+
+ std::string hashStr = "";
+ size_t allowedLen = 0;
+ switch (((RSA_PKCS_PSS_PARAMS*) param)->hashAlg)
+ {
+ case HashAlgo::SHA1:
+ hashStr = "SHA-160";
+ allowedLen = 20;
+ break;
+ case HashAlgo::SHA224:
+ hashStr = "SHA-224";
+ allowedLen = 28;
+ break;
+ case HashAlgo::SHA256:
+ hashStr = "SHA-256";
+ allowedLen = 32;
+ break;
+ case HashAlgo::SHA384:
+ hashStr = "SHA-384";
+ allowedLen = 48;
+ break;
+ case HashAlgo::SHA512:
+ hashStr = "SHA-512";
+ allowedLen = 64;
+ break;
+ default:
+ ERROR_MSG("Invalid hash parameter");
+ return "";
+ }
+
+ if (dataSize != allowedLen)
+ {
+ ERROR_MSG("Data to sign does not match expected (%d) for RSA PSS", (int)allowedLen);
+ return "";
+ }
+
+ size_t sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((bitLength+6)/8-2-20))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, bitLength);
+ return "";
+ }
+
+ std::ostringstream request;
+ request << "PSSR_Raw(" << hashStr << ",MGF1," << sLen << ")";
+ return request.str();
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSA.h b/SoftHSMv2/src/lib/crypto/BotanRSA.h
new file mode 100644
index 0000000..f9b6554
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSA.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSA.h
+
+ Botan RSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANRSA_H
+#define _SOFTHSM_V2_BOTANRSA_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include <botan/pubkey.h>
+
+class BotanRSA : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ BotanRSA();
+
+ // Destructor
+ virtual ~BotanRSA();
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ Botan::PK_Signer* signer;
+ Botan::PK_Verifier* verifier;
+
+#ifdef WITH_RAW_PSS
+ std::string getCipherRawPss(size_t bitLength, size_t dataSize, const void* param, const size_t paramLen);
+#endif
+};
+
+#endif // !_SOFTHSM_V2_BOTANRSA_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.cpp b/SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.cpp
new file mode 100644
index 0000000..76d9b5b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSAKeyPair.cpp
+
+ Botan RSA key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanRSAKeyPair.h"
+
+// Set the public key
+void BotanRSAKeyPair::setPublicKey(BotanRSAPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void BotanRSAKeyPair::setPrivateKey(BotanRSAPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* BotanRSAKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* BotanRSAKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* BotanRSAKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* BotanRSAKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.h b/SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.h
new file mode 100644
index 0000000..55f4955
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSAKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSAKeyPair.h
+
+ Botan RSA key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANRSAKEYPAIR_H
+#define _SOFTHSM_V2_BOTANRSAKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "BotanRSAPublicKey.h"
+#include "BotanRSAPrivateKey.h"
+
+class BotanRSAKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(BotanRSAPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(BotanRSAPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ BotanRSAPublicKey pubKey;
+
+ // The private key
+ BotanRSAPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_BOTANRSAKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.cpp
new file mode 100644
index 0000000..f600230
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSAPrivateKey.cpp
+
+ Botan RSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanRSAPrivateKey.h"
+#include "BotanUtil.h"
+#include "BotanRNG.h"
+#include "BotanCryptoFactory.h"
+#include <string.h>
+#include <botan/pkcs8.h>
+#include <botan/pkcs8.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/oids.h>
+#include <botan/version.h>
+
+// Constructors
+BotanRSAPrivateKey::BotanRSAPrivateKey()
+{
+ rsa = NULL;
+}
+
+BotanRSAPrivateKey::BotanRSAPrivateKey(const Botan::RSA_PrivateKey* inRSA)
+{
+ rsa = NULL;
+
+ setFromBotan(inRSA);
+}
+
+// Destructor
+BotanRSAPrivateKey::~BotanRSAPrivateKey()
+{
+ delete rsa;
+}
+
+// The type
+/*static*/ const char* BotanRSAPrivateKey::type = "Botan RSA Private Key";
+
+// Set from Botan representation
+void BotanRSAPrivateKey::setFromBotan(const Botan::RSA_PrivateKey* inRSA)
+{
+ ByteString inP = BotanUtil::bigInt2ByteString(inRSA->get_p());
+ setP(inP);
+ ByteString inQ = BotanUtil::bigInt2ByteString(inRSA->get_q());
+ setQ(inQ);
+ ByteString inDP1 = BotanUtil::bigInt2ByteString(inRSA->get_d1());
+ setDP1(inDP1);
+ ByteString inDQ1 = BotanUtil::bigInt2ByteString(inRSA->get_d2());
+ setDQ1(inDQ1);
+ ByteString inPQ = BotanUtil::bigInt2ByteString(inRSA->get_c());
+ setPQ(inPQ);
+ ByteString inD = BotanUtil::bigInt2ByteString(inRSA->get_d());
+ setD(inD);
+ ByteString inN = BotanUtil::bigInt2ByteString(inRSA->get_n());
+ setN(inN);
+ ByteString inE = BotanUtil::bigInt2ByteString(inRSA->get_e());
+ setE(inE);
+}
+
+// Check if the key is of the given type
+bool BotanRSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the RSA private key components
+void BotanRSAPrivateKey::setP(const ByteString& inP)
+{
+ RSAPrivateKey::setP(inP);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPrivateKey::setQ(const ByteString& inQ)
+{
+ RSAPrivateKey::setQ(inQ);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPrivateKey::setPQ(const ByteString& inPQ)
+{
+ RSAPrivateKey::setPQ(inPQ);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPrivateKey::setDP1(const ByteString& inDP1)
+{
+ RSAPrivateKey::setDP1(inDP1);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPrivateKey::setDQ1(const ByteString& inDQ1)
+{
+ RSAPrivateKey::setDQ1(inDQ1);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPrivateKey::setD(const ByteString& inD)
+{
+ RSAPrivateKey::setD(inD);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+
+// Setters for the RSA public key components
+void BotanRSAPrivateKey::setN(const ByteString& inN)
+{
+ RSAPrivateKey::setN(inN);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPrivateKey::setE(const ByteString& inE)
+{
+ RSAPrivateKey::setE(inE);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString BotanRSAPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ createBotanKey();
+ if (rsa == NULL) return der;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ const Botan::secure_vector<Botan::byte> ber = Botan::PKCS8::BER_encode(*rsa);
+#else
+ const Botan::SecureVector<Botan::byte> ber = Botan::PKCS8::BER_encode(*rsa);
+#endif
+ der.resize(ber.size());
+ memcpy(&der[0], &ber[0], ber.size());
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool BotanRSAPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ Botan::DataSource_Memory source(ber.const_byte_str(), ber.size());
+ if (source.end_of_data()) return false;
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> keydata;
+#else
+ Botan::SecureVector<Botan::byte> keydata;
+#endif
+ Botan::AlgorithmIdentifier alg_id;
+ Botan::RSA_PrivateKey* key = NULL;
+ try
+ {
+
+ Botan::BER_Decoder(source)
+ .start_cons(Botan::SEQUENCE)
+ .decode_and_check<size_t>(0, "Unknown PKCS #8 version number")
+ .decode(alg_id)
+ .decode(keydata, Botan::OCTET_STRING)
+ .discard_remaining()
+ .end_cons();
+ if (keydata.empty())
+ throw Botan::Decoding_Error("PKCS #8 private key decoding failed");
+ if (Botan::OIDS::lookup(alg_id.oid).compare("RSA"))
+ {
+ ERROR_MSG("Decoded private key not RSA");
+
+ return false;
+ }
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
+ key = new Botan::RSA_PrivateKey(alg_id, keydata);
+#else
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ key = new Botan::RSA_PrivateKey(alg_id, keydata, *rng->getRNG());
+#endif
+ if (key == NULL) return false;
+
+ setFromBotan(key);
+
+ delete key;
+ }
+ catch (std::exception& e)
+ {
+ ERROR_MSG("Decode failed on %s", e.what());
+
+ return false;
+ }
+
+ return true;
+}
+
+// Retrieve the Botan representation of the key
+Botan::RSA_PrivateKey* BotanRSAPrivateKey::getBotanKey()
+{
+ if (!rsa)
+ {
+ createBotanKey();
+ }
+
+ return rsa;
+}
+
+// Create the Botan representation of the key
+void BotanRSAPrivateKey::createBotanKey()
+{
+ // d and n is not needed, they can be calculated
+ if (p.size() != 0 &&
+ q.size() != 0 &&
+ e.size() != 0)
+ {
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,34)
+ rsa = new Botan::RSA_PrivateKey(
+ BotanUtil::byteString2bigInt(p),
+ BotanUtil::byteString2bigInt(q),
+ BotanUtil::byteString2bigInt(e),
+ BotanUtil::byteString2bigInt(d),
+ BotanUtil::byteString2bigInt(n));
+#else
+ BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
+ rsa = new Botan::RSA_PrivateKey(*rng->getRNG(),
+ BotanUtil::byteString2bigInt(p),
+ BotanUtil::byteString2bigInt(q),
+ BotanUtil::byteString2bigInt(e),
+ BotanUtil::byteString2bigInt(d),
+ BotanUtil::byteString2bigInt(n));
+#endif
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan private key");
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.h
new file mode 100644
index 0000000..7664a86
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSAPrivateKey.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSAPrivateKey.h
+
+ Botan RSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANRSAPRIVATEKEY_H
+#define _SOFTHSM_V2_BOTANRSAPRIVATEKEY_H
+
+#include "config.h"
+#include "RSAPrivateKey.h"
+#include <botan/rsa.h>
+
+class BotanRSAPrivateKey : public RSAPrivateKey
+{
+public:
+ // Constructors
+ BotanRSAPrivateKey();
+
+ BotanRSAPrivateKey(const Botan::RSA_PrivateKey* inRSA);
+
+ // Destructor
+ virtual ~BotanRSAPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the RSA private key components
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setPQ(const ByteString& inPQ);
+ virtual void setDP1(const ByteString& inDP1);
+ virtual void setDQ1(const ByteString& inDQ1);
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the RSA public key components
+ virtual void setN(const ByteString& inN);
+ virtual void setE(const ByteString& inE);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::RSA_PrivateKey* inRSA);
+
+ // Retrieve the Botan representation of the key
+ Botan::RSA_PrivateKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::RSA_PrivateKey* rsa;
+
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLRSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.cpp
new file mode 100644
index 0000000..63bc82c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSAPublicKey.cpp
+
+ Botan RSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "BotanRSAPublicKey.h"
+#include "BotanUtil.h"
+#include <string.h>
+
+// Constructors
+BotanRSAPublicKey::BotanRSAPublicKey()
+{
+ rsa = NULL;
+}
+
+BotanRSAPublicKey::BotanRSAPublicKey(const Botan::RSA_PublicKey* inRSA)
+{
+ rsa = NULL;
+
+ setFromBotan(inRSA);
+}
+
+// Destructor
+BotanRSAPublicKey::~BotanRSAPublicKey()
+{
+ delete rsa;
+}
+
+// The type
+/*static*/ const char* BotanRSAPublicKey::type = "Botan RSA Public Key";
+
+// Check if the key is of the given type
+bool BotanRSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Set from OpenSSL representation
+void BotanRSAPublicKey::setFromBotan(const Botan::RSA_PublicKey* inRSA)
+{
+ ByteString inN = BotanUtil::bigInt2ByteString(inRSA->get_n());
+ setN(inN);
+ ByteString inE = BotanUtil::bigInt2ByteString(inRSA->get_e());
+ setE(inE);
+}
+
+// Setters for the RSA public key components
+void BotanRSAPublicKey::setN(const ByteString& inN)
+{
+ RSAPublicKey::setN(inN);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+void BotanRSAPublicKey::setE(const ByteString& inE)
+{
+ RSAPublicKey::setE(inE);
+
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+}
+
+// Retrieve the Botan representation of the key
+Botan::RSA_PublicKey* BotanRSAPublicKey::getBotanKey()
+{
+ if (!rsa)
+ {
+ createBotanKey();
+ }
+
+ return rsa;
+}
+
+// Create the Botan representation of the key
+void BotanRSAPublicKey::createBotanKey()
+{
+ if (n.size() != 0 && e.size() != 0)
+ {
+ if (rsa)
+ {
+ delete rsa;
+ rsa = NULL;
+ }
+
+ try
+ {
+ rsa = new Botan::RSA_PublicKey(BotanUtil::byteString2bigInt(n),
+ BotanUtil::byteString2bigInt(e));
+ }
+ catch (...)
+ {
+ ERROR_MSG("Could not create the Botan public key");
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.h b/SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.h
new file mode 100644
index 0000000..a0c0026
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanRSAPublicKey.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanRSAPublicKey.h
+
+ Botan RSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANRSAPUBLICKEY_H
+#define _SOFTHSM_V2_BOTANRSAPUBLICKEY_H
+
+#include "config.h"
+#include "RSAPublicKey.h"
+#include <botan/rsa.h>
+
+class BotanRSAPublicKey : public RSAPublicKey
+{
+public:
+ // Constructors
+ BotanRSAPublicKey();
+
+ BotanRSAPublicKey(const Botan::RSA_PublicKey* inRSA);
+
+ // Destructor
+ virtual ~BotanRSAPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the RSA public key components
+ virtual void setN(const ByteString& inN);
+ virtual void setE(const ByteString& inE);
+
+ // Set from Botan representation
+ virtual void setFromBotan(const Botan::RSA_PublicKey* inRSA);
+
+ // Retrieve the Botan representation of the key
+ Botan::RSA_PublicKey* getBotanKey();
+
+private:
+ // The internal Botan representation
+ Botan::RSA_PublicKey* rsa;
+
+ void createBotanKey();
+};
+
+#endif // !_SOFTHSM_V2_BOTANRSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA1.cpp b/SoftHSMv2/src/lib/crypto/BotanSHA1.cpp
new file mode 100644
index 0000000..35846ec
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA1.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA1.cpp
+
+ Botan SHA1 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanSHA1.h"
+#include <botan/sha160.h>
+
+int BotanSHA1::getHashSize()
+{
+ return 20;
+}
+
+Botan::HashFunction* BotanSHA1::getHash() const
+{
+ return new Botan::SHA_160();
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA1.h b/SoftHSMv2/src/lib/crypto/BotanSHA1.h
new file mode 100644
index 0000000..ca336b0
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA1.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA1.h
+
+ Botan SHA1 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANSHA1_H
+#define _SOFTHSM_V2_BOTANSHA1_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanSHA1 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANSHA1_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA224.cpp b/SoftHSMv2/src/lib/crypto/BotanSHA224.cpp
new file mode 100644
index 0000000..f1d2268
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA224.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA224.cpp
+
+ Botan SHA224 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanSHA224.h"
+#include <botan/sha2_32.h>
+
+int BotanSHA224::getHashSize()
+{
+ return 28;
+}
+
+Botan::HashFunction* BotanSHA224::getHash() const
+{
+ return new Botan::SHA_224();
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA224.h b/SoftHSMv2/src/lib/crypto/BotanSHA224.h
new file mode 100644
index 0000000..61fe16c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA224.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA224.h
+
+ Botan SHA224 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANSHA224_H
+#define _SOFTHSM_V2_BOTANSHA224_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanSHA224 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANSHA224_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA256.cpp b/SoftHSMv2/src/lib/crypto/BotanSHA256.cpp
new file mode 100644
index 0000000..878dece
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA256.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA256.cpp
+
+ Botan SHA256 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanSHA256.h"
+#include <botan/sha2_32.h>
+
+int BotanSHA256::getHashSize()
+{
+ return 32;
+}
+
+Botan::HashFunction* BotanSHA256::getHash() const
+{
+ return new Botan::SHA_256();
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA256.h b/SoftHSMv2/src/lib/crypto/BotanSHA256.h
new file mode 100644
index 0000000..5561f3c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA256.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA256.h
+
+ Botan SHA256 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANSHA256_H
+#define _SOFTHSM_V2_BOTANSHA256_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanSHA256 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANSHA256_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA384.cpp b/SoftHSMv2/src/lib/crypto/BotanSHA384.cpp
new file mode 100644
index 0000000..b7a1e09
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA384.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA384.cpp
+
+ Botan SHA384 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanSHA384.h"
+#include <botan/sha2_64.h>
+
+int BotanSHA384::getHashSize()
+{
+ return 48;
+}
+
+Botan::HashFunction* BotanSHA384::getHash() const
+{
+ return new Botan::SHA_384();
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA384.h b/SoftHSMv2/src/lib/crypto/BotanSHA384.h
new file mode 100644
index 0000000..5cf5d98
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA384.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA384.h
+
+ Botan SHA384 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANSHA384_H
+#define _SOFTHSM_V2_BOTANSHA384_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanSHA384 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANSHA384_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA512.cpp b/SoftHSMv2/src/lib/crypto/BotanSHA512.cpp
new file mode 100644
index 0000000..b7aa459
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA512.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA512.cpp
+
+ Botan SHA512 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanSHA512.h"
+#include <botan/sha2_64.h>
+
+int BotanSHA512::getHashSize()
+{
+ return 64;
+}
+
+Botan::HashFunction* BotanSHA512::getHash() const
+{
+ return new Botan::SHA_512();
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanSHA512.h b/SoftHSMv2/src/lib/crypto/BotanSHA512.h
new file mode 100644
index 0000000..d72416e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSHA512.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSHA512.h
+
+ Botan SHA512 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANSHA512_H
+#define _SOFTHSM_V2_BOTANSHA512_H
+
+#include "config.h"
+#include "BotanHashAlgorithm.h"
+#include <botan/hash.h>
+
+class BotanSHA512 : public BotanHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual Botan::HashFunction* getHash() const;
+};
+
+#endif // !_SOFTHSM_V2_BOTANSHA512_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.cpp
new file mode 100644
index 0000000..3f13892
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.cpp
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// TODO: Store context in securely allocated memory
+
+/*****************************************************************************
+ BotanSymmetricAlgorithm.cpp
+
+ Botan symmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanSymmetricAlgorithm.h"
+#include "BotanUtil.h"
+#include "salloc.h"
+#include <iostream>
+
+#include <botan/symkey.h>
+#include <botan/botan.h>
+#include <botan/version.h>
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,14)
+#include <botan/key_filt.h>
+#endif
+
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+#include "Botan_ecb.h"
+#include <botan/cipher_filter.h>
+#endif
+
+#ifdef WITH_AES_GCM
+#include <botan/aead.h>
+#endif
+
+// Constructor
+BotanSymmetricAlgorithm::BotanSymmetricAlgorithm()
+{
+ cryption = NULL;
+ maximumBytes = Botan::BigInt(1);
+ maximumBytes.flip_sign();
+ counterBytes = Botan::BigInt(0);
+}
+
+// Destructor
+BotanSymmetricAlgorithm::~BotanSymmetricAlgorithm()
+{
+ delete cryption;
+ cryption = NULL;
+}
+
+// Encryption functions
+bool BotanSymmetricAlgorithm::encryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode:CBC */, const ByteString& IV /* = ByteString()*/, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& aad /* = ByteString() */, size_t tagBytes /* = 0 */)
+{
+ // Call the superclass initialiser
+ if (!SymmetricAlgorithm::encryptInit(key, mode, IV, padding, counterBits, aad, tagBytes))
+ {
+ return false;
+ }
+
+ // Check the IV
+ if (mode != SymMode::GCM && (IV.size() > 0) && (IV.size() != getBlockSize()))
+ {
+ ERROR_MSG("Invalid IV size (%d bytes, expected %d bytes)", IV.size(), getBlockSize());
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ ByteString iv;
+
+ if (IV.size() > 0)
+ {
+ iv = IV;
+ }
+ else
+ {
+ iv.wipe(getBlockSize());
+ }
+
+ // Check the counter bits
+ if (counterBits > 0)
+ {
+ Botan::BigInt counter = BotanUtil::byteString2bigInt(iv);
+ counter.mask_bits(counterBits);
+
+ // Reverse the bits
+ while (counterBits > 0)
+ {
+ counterBits--;
+ if (counter.get_bit(counterBits))
+ {
+ counter.clear_bit(counterBits);
+ }
+ else
+ {
+ counter.set_bit(counterBits);
+ }
+ }
+
+ // Set the maximum bytes
+ maximumBytes = (counter + 1) * getBlockSize();
+ counterBytes = Botan::BigInt(0);
+ }
+ else
+ {
+ maximumBytes = Botan::BigInt(1);
+ maximumBytes.flip_sign();
+ }
+
+ // Determine the cipher
+ std::string cipherName = getCipher();
+
+ if (cipherName == "")
+ {
+ ERROR_MSG("Invalid encryption cipher");
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ // Allocate the context
+ try
+ {
+ Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+ if (mode == SymMode::ECB)
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+ // ECB cipher mode was dropped in Botan 2.0
+ const std::vector<std::string> algo_parts = Botan::split_on(cipherName, '/');
+ const std::string cipher_name = algo_parts[0];
+ Botan::BlockCipherModePaddingMethod* pad;
+ if (algo_parts.size() == 3 && algo_parts[2] == "PKCS7")
+ {
+ pad = new Botan::PKCS7_Padding();
+ }
+ else
+ {
+ pad = new Botan::Null_Padding();
+ }
+ std::unique_ptr<Botan::BlockCipher> bc(Botan::BlockCipher::create(cipher_name));
+ Botan::Keyed_Filter* cipher = new Botan::Cipher_Mode_Filter(new Botan::ECB_Encryption(bc.release(),pad));
+ cipher->set_key(botanKey);
+ cryption = new Botan::Pipe(cipher);
+#else
+ cryption = new Botan::Pipe(Botan::get_cipher(cipherName, botanKey, Botan::ENCRYPTION));
+#endif
+ }
+#ifdef WITH_AES_GCM
+ else if (mode == SymMode::GCM)
+ {
+ Botan::AEAD_Mode* aead = Botan::get_aead(cipherName, Botan::ENCRYPTION);
+ aead->set_key(botanKey);
+ aead->set_associated_data(aad.const_byte_str(), aad.size());
+
+ Botan::InitializationVector botanIV = Botan::InitializationVector(IV.const_byte_str(), IV.size());
+ Botan::Keyed_Filter* filter = new Botan::Cipher_Mode_Filter(aead);
+ filter->set_iv(botanIV);
+ cryption = new Botan::Pipe(filter);
+ }
+#endif
+ else
+ {
+ Botan::InitializationVector botanIV = Botan::InitializationVector(IV.const_byte_str(), IV.size());
+ cryption = new Botan::Pipe(Botan::get_cipher(cipherName, botanKey, botanIV, Botan::ENCRYPTION));
+ }
+ cryption->start_msg();
+ }
+ catch (std::exception &e)
+ {
+ ERROR_MSG("Failed to create the encryption token: %s", e.what());
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanSymmetricAlgorithm::encryptUpdate(const ByteString& data, ByteString& encryptedData)
+{
+ if (!SymmetricAlgorithm::encryptUpdate(data, encryptedData))
+ {
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Write data
+ try
+ {
+ if (data.size() > 0)
+ cryption->write(data.const_byte_str(), data.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to write to the encryption token");
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Count number of bytes written
+ if (maximumBytes.is_positive())
+ {
+ counterBytes += data.size();
+ }
+
+ // Read data
+ int bytesRead = 0;
+ try
+ {
+ size_t outLen = cryption->remaining();
+ encryptedData.resize(outLen);
+ if (outLen > 0)
+ bytesRead = cryption->read(&encryptedData[0], outLen);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to encrypt the data");
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Resize the output block
+ encryptedData.resize(bytesRead);
+ currentBufferSize -= bytesRead;
+
+ return true;
+}
+
+bool BotanSymmetricAlgorithm::encryptFinal(ByteString& encryptedData)
+{
+ if (!SymmetricAlgorithm::encryptFinal(encryptedData))
+ {
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Read data
+ int bytesRead = 0;
+ try
+ {
+ cryption->end_msg();
+ size_t outLen = cryption->remaining();
+ encryptedData.resize(outLen);
+ if (outLen > 0)
+ bytesRead = cryption->read(&encryptedData[0], outLen);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to encrypt the data");
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Clean up
+ delete cryption;
+ cryption = NULL;
+
+ // Resize the output block
+ encryptedData.resize(bytesRead);
+
+ return true;
+}
+
+// Decryption functions
+bool BotanSymmetricAlgorithm::decryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& IV /* = ByteString() */, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& aad /* = ByteString() */, size_t tagBytes /* = 0 */)
+{
+ // Call the superclass initialiser
+ if (!SymmetricAlgorithm::decryptInit(key, mode, IV, padding, counterBits, aad, tagBytes))
+ {
+ return false;
+ }
+
+ // Check the IV
+ if (mode != SymMode::GCM && (IV.size() > 0) && (IV.size() != getBlockSize()))
+ {
+ ERROR_MSG("Invalid IV size (%d bytes, expected %d bytes)", IV.size(), getBlockSize());
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ ByteString iv;
+
+ if (IV.size() > 0)
+ {
+ iv = IV;
+ }
+ else
+ {
+ iv.wipe(getBlockSize());
+ }
+
+ // Check the counter bits
+ if (counterBits > 0)
+ {
+ Botan::BigInt counter = BotanUtil::byteString2bigInt(iv);
+ counter.mask_bits(counterBits);
+
+ // Reverse the bits
+ while (counterBits > 0)
+ {
+ counterBits--;
+ if (counter.get_bit(counterBits))
+ {
+ counter.clear_bit(counterBits);
+ }
+ else
+ {
+ counter.set_bit(counterBits);
+ }
+ }
+
+ // Set the maximum bytes
+ maximumBytes = (counter + 1) * getBlockSize();
+ counterBytes = Botan::BigInt(0);
+ }
+ else
+ {
+ maximumBytes = Botan::BigInt(1);
+ maximumBytes.flip_sign();
+ }
+
+ // Determine the cipher class
+ std::string cipherName = getCipher();
+
+ if (cipherName == "")
+ {
+ ERROR_MSG("Invalid decryption cipher");
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ // Allocate the context
+ try
+ {
+ Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
+ if (mode == SymMode::ECB)
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+ // ECB cipher mode was dropped in Botan 2.0
+ const std::vector<std::string> algo_parts = Botan::split_on(cipherName, '/');
+ const std::string cipher_name = algo_parts[0];
+ Botan::BlockCipherModePaddingMethod* pad;
+ if (algo_parts.size() == 3 && algo_parts[2] == "PKCS7")
+ {
+ pad = new Botan::PKCS7_Padding();
+ }
+ else
+ {
+ pad = new Botan::Null_Padding();
+ }
+ std::unique_ptr<Botan::BlockCipher> bc(Botan::BlockCipher::create(cipher_name));
+ Botan::Keyed_Filter* cipher = new Botan::Cipher_Mode_Filter(new Botan::ECB_Decryption(bc.release(),pad));
+ cipher->set_key(botanKey);
+ cryption = new Botan::Pipe(cipher);
+#else
+ cryption = new Botan::Pipe(Botan::get_cipher(cipherName, botanKey, Botan::DECRYPTION));
+#endif
+ }
+#ifdef WITH_AES_GCM
+ else if (mode == SymMode::GCM)
+ {
+ Botan::AEAD_Mode* aead = Botan::get_aead(cipherName, Botan::DECRYPTION);
+ aead->set_key(botanKey);
+ aead->set_associated_data(aad.const_byte_str(), aad.size());
+
+ Botan::InitializationVector botanIV = Botan::InitializationVector(IV.const_byte_str(), IV.size());
+ Botan::Keyed_Filter* filter = new Botan::Cipher_Mode_Filter(aead);
+ filter->set_iv(botanIV);
+ cryption = new Botan::Pipe(filter);
+ }
+#endif
+ else
+ {
+ Botan::InitializationVector botanIV = Botan::InitializationVector(IV.const_byte_str(), IV.size());
+ cryption = new Botan::Pipe(Botan::get_cipher(cipherName, botanKey, botanIV, Botan::DECRYPTION));
+ }
+ cryption->start_msg();
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to create the decryption token");
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ return true;
+}
+
+bool BotanSymmetricAlgorithm::decryptUpdate(const ByteString& encryptedData, ByteString& data)
+{
+ if (!SymmetricAlgorithm::decryptUpdate(encryptedData, data))
+ {
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // AEAD ciphers should not return decrypted data until final is called
+ if (currentCipherMode == SymMode::GCM)
+ {
+ data.resize(0);
+ return true;
+ }
+
+ // Write data
+ try
+ {
+ if (encryptedData.size() > 0)
+ cryption->write(encryptedData.const_byte_str(), encryptedData.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to write to the decryption token");
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Count number of bytes written
+ if (maximumBytes.is_positive())
+ {
+ counterBytes += encryptedData.size();
+ }
+
+ // Read data
+ int bytesRead = 0;
+ try
+ {
+ size_t outLen = cryption->remaining();
+ data.resize(outLen);
+ if (outLen > 0)
+ bytesRead = cryption->read(&data[0], outLen);
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to decrypt the data");
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Resize the output block
+ data.resize(bytesRead);
+ currentBufferSize -= bytesRead;
+
+ return true;
+}
+
+bool BotanSymmetricAlgorithm::decryptFinal(ByteString& data)
+{
+ SymMode::Type mode = currentCipherMode;
+ ByteString aeadBuffer = currentAEADBuffer;
+
+ if (!SymmetricAlgorithm::decryptFinal(data))
+ {
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ if (mode == SymMode::GCM)
+ {
+ // Write data
+ try
+ {
+ if (aeadBuffer.size() > 0)
+ cryption->write(aeadBuffer.const_byte_str(), aeadBuffer.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Failed to write to the decryption token");
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+ }
+
+ // Read data
+ int bytesRead = 0;
+ try
+ {
+ cryption->end_msg();
+ size_t outLen = cryption->remaining();
+ data.resize(outLen);
+ if (outLen > 0)
+ bytesRead = cryption->read(&data[0], outLen);
+ }
+ catch (std::exception &e)
+ {
+ ERROR_MSG("Failed to decrypt the data: %s", e.what());
+
+ delete cryption;
+ cryption = NULL;
+
+ return false;
+ }
+
+ // Clean up
+ delete cryption;
+ cryption = NULL;
+
+ // Resize the output block
+ data.resize(bytesRead);
+
+ return true;
+}
+
+// Check if more bytes of data can be encrypted
+bool BotanSymmetricAlgorithm::checkMaximumBytes(unsigned long bytes)
+{
+ if (maximumBytes.is_negative()) return true;
+
+ if (maximumBytes.cmp(counterBytes + bytes) >= 0) return true;
+
+ return false;
+}
diff --git a/SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.h b/SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.h
new file mode 100644
index 0000000..3031094
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanSymmetricAlgorithm.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanSymmetricAlgorithm.h
+
+ Botan symmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANSYMMETRICALGORITHM_H
+#define _SOFTHSM_V2_BOTANSYMMETRICALGORITHM_H
+
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "SymmetricAlgorithm.h"
+
+#include <botan/pipe.h>
+#include <botan/bigint.h>
+
+class BotanSymmetricAlgorithm : public SymmetricAlgorithm
+{
+public:
+ // Constructor
+ BotanSymmetricAlgorithm();
+
+ // Destructor
+ virtual ~BotanSymmetricAlgorithm();
+
+ // Encryption functions
+ virtual bool encryptInit(const SymmetricKey* key, const SymMode::Type mode = SymMode::CBC, const ByteString& IV = ByteString(), bool padding = true, size_t counterBits = 0, const ByteString& aad = ByteString(), size_t tagBytes = 0);
+ virtual bool encryptUpdate(const ByteString& data, ByteString& encryptedData);
+ virtual bool encryptFinal(ByteString& encryptedData);
+
+ // Decryption functions
+ virtual bool decryptInit(const SymmetricKey* key, const SymMode::Type mode = SymMode::CBC, const ByteString& IV = ByteString(), bool padding = true, size_t counterBits = 0, const ByteString& aad = ByteString(), size_t tagBytes = 0);
+ virtual bool decryptUpdate(const ByteString& encryptedData, ByteString& data);
+ virtual bool decryptFinal(ByteString& data);
+
+ // Return the block size
+ virtual size_t getBlockSize() const = 0;
+
+ // Check if more bytes of data can be encrypted
+ virtual bool checkMaximumBytes(unsigned long bytes);
+
+protected:
+ // Return the right cipher for the operation
+ virtual std::string getCipher() const = 0;
+
+private:
+ // The current context
+ Botan::Pipe* cryption;
+
+ // The maximum bytes to encrypt/decrypt
+ Botan::BigInt maximumBytes;
+ Botan::BigInt counterBytes;
+};
+
+#endif // !_SOFTHSM_V2_BOTANSYMMETRICALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/BotanUtil.cpp b/SoftHSMv2/src/lib/crypto/BotanUtil.cpp
new file mode 100644
index 0000000..e5da460
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanUtil.cpp
@@ -0,0 +1,146 @@
+ /*
+ * Copyright (c) .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanUtil.h
+
+ Botan convenience functions
+ *****************************************************************************/
+
+#include "config.h"
+#include "BotanUtil.h"
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <botan/asn1_obj.h>
+#include <botan/version.h>
+
+// Convert a Botan BigInt to a ByteString
+ByteString BotanUtil::bigInt2ByteString(const Botan::BigInt& bigInt)
+{
+ ByteString rv;
+
+ rv.resize(bigInt.bytes());
+ bigInt.binary_encode(&rv[0]);
+
+ return rv;
+}
+
+// Used when extracting little-endian data
+ByteString BotanUtil::bigInt2ByteStringPrefix(const Botan::BigInt& bigInt, size_t size)
+{
+ ByteString rv;
+
+ if (size > bigInt.bytes())
+ {
+ size_t diff = size - bigInt.bytes();
+ rv.resize(size);
+
+ memset(&rv[0], '\0', diff);
+
+ bigInt.binary_encode(&rv[0] + diff);
+ }
+ else
+ {
+ rv.resize(bigInt.bytes());
+ bigInt.binary_encode(&rv[0]);
+ }
+
+ return rv;
+}
+
+// Convert a ByteString to an Botan BigInt
+Botan::BigInt BotanUtil::byteString2bigInt(const ByteString& byteString)
+{
+ return Botan::BigInt(byteString.const_byte_str(), byteString.size());
+}
+
+#if defined(WITH_ECC) || defined(WITH_GOST)
+// Convert a Botan EC group to a ByteString
+ByteString BotanUtil::ecGroup2ByteString(const Botan::EC_Group& ecGroup)
+{
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> der = ecGroup.DER_encode(Botan::EC_DOMPAR_ENC_OID);
+#else
+ Botan::SecureVector<Botan::byte> der = ecGroup.DER_encode(Botan::EC_DOMPAR_ENC_OID);
+#endif
+ return ByteString(&der[0], der.size());
+}
+
+// Convert a ByteString to a Botan EC group
+Botan::EC_Group BotanUtil::byteString2ECGroup(const ByteString& byteString)
+{
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> der(byteString.size());
+ memcpy(&der[0], byteString.const_byte_str(), byteString.size());
+ return Botan::EC_Group(der);
+#else
+ return Botan::EC_Group(Botan::MemoryVector<Botan::byte>(byteString.const_byte_str(), byteString.size()));
+#endif
+}
+
+// Convert a Botan EC point to a ByteString
+ByteString BotanUtil::ecPoint2ByteString(const Botan::PointGFp& ecPoint)
+{
+ ByteString point;
+
+ try
+ {
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ Botan::secure_vector<Botan::byte> repr = Botan::EC2OSP(ecPoint, Botan::PointGFp::UNCOMPRESSED);
+ Botan::secure_vector<Botan::byte> der;
+#else
+ Botan::SecureVector<Botan::byte> repr = Botan::EC2OSP(ecPoint, Botan::PointGFp::UNCOMPRESSED);
+ Botan::SecureVector<Botan::byte> der;
+#endif
+
+
+ der = Botan::DER_Encoder()
+ .encode(repr, Botan::OCTET_STRING)
+ .get_contents();
+ point.resize(der.size());
+ memcpy(&point[0], &der[0], der.size());
+ }
+ catch (...)
+ {
+ ERROR_MSG("Can't convert from EC point");
+ }
+ return point;
+}
+
+// Convert a ByteString to a Botan EC point
+Botan::PointGFp BotanUtil::byteString2ECPoint(const ByteString& byteString, const Botan::EC_Group& ecGroup)
+{
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+ std::vector<Botan::byte> repr;
+#else
+ Botan::SecureVector<Botan::byte> repr;
+#endif
+ Botan::BER_Decoder(byteString.const_byte_str(), byteString.size())
+ .decode(repr, Botan::OCTET_STRING)
+ .verify_end();
+ return Botan::OS2ECP(&repr[0], repr.size(), ecGroup.get_curve());
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/BotanUtil.h b/SoftHSMv2/src/lib/crypto/BotanUtil.h
new file mode 100644
index 0000000..67f6ca6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/BotanUtil.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ BotanUtil.h
+
+ Botan convenience functions
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_BOTANUTIL_H
+#define _SOFTHSM_V2_BOTANUTIL_H
+
+#include "config.h"
+#include "ByteString.h"
+#include <botan/bigint.h>
+#if defined(WITH_ECC) || defined(WITH_GOST)
+#include <botan/ec_group.h>
+#endif
+
+namespace BotanUtil
+{
+ // Convert a Botan BigInt to a ByteString
+ ByteString bigInt2ByteString(const Botan::BigInt& bigInt);
+ ByteString bigInt2ByteStringPrefix(const Botan::BigInt& bigInt, size_t size);
+
+ // Convert a ByteString to a Botan BigInt
+ Botan::BigInt byteString2bigInt(const ByteString& byteString);
+
+#if defined(WITH_ECC) || defined(WITH_GOST)
+ // Convert a Botan EC group to a ByteString
+ ByteString ecGroup2ByteString(const Botan::EC_Group& ecGroup);
+
+ // Convert a ByteString to a Botan EC group
+ Botan::EC_Group byteString2ECGroup(const ByteString& byteString);
+
+ // Convert a Botan EC point to a ByteString
+ ByteString ecPoint2ByteString(const Botan::PointGFp& ecPoint);
+
+ // Convert a ByteString to a Botan EC point in the given EC group
+ Botan::PointGFp byteString2ECPoint(const ByteString& byteString, const Botan::EC_Group& ecGroup);
+#endif
+}
+
+#endif // !_SOFTHSM_V2_BOTANUTIL_H
+
diff --git a/SoftHSMv2/src/lib/crypto/Botan_ecb.cpp b/SoftHSMv2/src/lib/crypto/Botan_ecb.cpp
new file mode 100644
index 0000000..f27276e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/Botan_ecb.cpp
@@ -0,0 +1,153 @@
+/*
+* ECB Mode
+* (C) 1999-2009,2013 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/version.h>
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+// ECB cipher mode was dropped in Botan 2.0.0
+// so including this code in SoftHSM for continued support
+// for e.g. CKA_VALUE_CHECK
+
+#include "Botan_ecb.h"
+#include "Botan_rounding.h"
+
+namespace Botan {
+
+ECB_Mode::ECB_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
+ m_cipher(cipher),
+ m_padding(padding)
+ {
+ if(!m_padding->valid_blocksize(cipher->block_size()))
+ throw Invalid_Argument("Padding " + m_padding->name() +
+ " cannot be used with " +
+ cipher->name() + "/ECB");
+ }
+
+void ECB_Mode::clear()
+ {
+ m_cipher->clear();
+ }
+
+void ECB_Mode::reset()
+ {
+ // no msg state here
+ return;
+ }
+
+std::string ECB_Mode::name() const
+ {
+ return cipher().name() + "/ECB/" + padding().name();
+ }
+
+size_t ECB_Mode::update_granularity() const
+ {
+ return cipher().parallel_bytes();
+ }
+
+Key_Length_Specification ECB_Mode::key_spec() const
+ {
+ return cipher().key_spec();
+ }
+
+size_t ECB_Mode::default_nonce_length() const
+ {
+ return 0;
+ }
+
+bool ECB_Mode::valid_nonce_length(size_t n) const
+ {
+ return (n == 0);
+ }
+
+void ECB_Mode::key_schedule(const byte key[], size_t length)
+ {
+ m_cipher->set_key(key, length);
+ }
+
+void ECB_Mode::start_msg(const byte[], size_t nonce_len)
+ {
+ if(nonce_len != 0)
+ throw Invalid_IV_Length(name(), nonce_len);
+ }
+
+size_t ECB_Encryption::minimum_final_size() const
+ {
+ return 0;
+ }
+
+size_t ECB_Encryption::output_length(size_t input_length) const
+ {
+ if(input_length == 0)
+ return cipher().block_size();
+ else
+ return round_up(input_length, cipher().block_size());
+ }
+
+size_t ECB_Encryption::process(uint8_t buf[], size_t sz)
+ {
+ const size_t BS = cipher().block_size();
+ BOTAN_ASSERT(sz % BS == 0, "ECB input is full blocks");
+ const size_t blocks = sz / BS;
+ cipher().encrypt_n(buf, buf, blocks);
+ return sz;
+ }
+
+void ECB_Encryption::finish(secure_vector<byte>& buffer, size_t offset)
+ {
+ BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
+ const size_t sz = buffer.size() - offset;
+
+ const size_t BS = cipher().block_size();
+
+ const size_t bytes_in_final_block = sz % BS;
+
+ padding().add_padding(buffer, bytes_in_final_block, BS);
+
+ if(buffer.size() % BS)
+ throw Exception("Did not pad to full block size in " + name());
+
+ update(buffer, offset);
+ }
+
+size_t ECB_Decryption::output_length(size_t input_length) const
+ {
+ return input_length;
+ }
+
+size_t ECB_Decryption::minimum_final_size() const
+ {
+ return cipher().block_size();
+ }
+
+size_t ECB_Decryption::process(uint8_t buf[], size_t sz)
+ {
+ const size_t BS = cipher().block_size();
+ BOTAN_ASSERT(sz % BS == 0, "Input is full blocks");
+ size_t blocks = sz / BS;
+ cipher().decrypt_n(buf, buf, blocks);
+ return sz;
+ }
+
+void ECB_Decryption::finish(secure_vector<byte>& buffer, size_t offset)
+ {
+ BOTAN_ASSERT(buffer.size() >= offset, "Offset is sane");
+ const size_t sz = buffer.size() - offset;
+
+ const size_t BS = cipher().block_size();
+
+ if(sz == 0 || sz % BS)
+ throw Decoding_Error(name() + ": Ciphertext not a multiple of block size");
+
+ update(buffer, offset);
+
+ const size_t pad_bytes = BS - padding().unpad(&buffer[buffer.size()-BS], BS);
+ buffer.resize(buffer.size() - pad_bytes); // remove padding
+ }
+
+}
+
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/Botan_ecb.h b/SoftHSMv2/src/lib/crypto/Botan_ecb.h
new file mode 100644
index 0000000..1712083
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/Botan_ecb.h
@@ -0,0 +1,107 @@
+/*
+* ECB Mode
+* (C) 1999-2009,2013 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_MODE_ECB_H__
+#define BOTAN_MODE_ECB_H__
+
+#include <botan/version.h>
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+// ECB cipher mode was dropped in Botan 2.0.0
+// so including this code in SoftHSM for continued support
+// for e.g. CKA_VALUE_CHECK
+
+#include <botan/cipher_mode.h>
+#include <botan/block_cipher.h>
+#include <botan/mode_pad.h>
+
+namespace Botan {
+
+/**
+* ECB mode
+*/
+class BOTAN_DLL ECB_Mode : public Cipher_Mode
+ {
+ public:
+ std::string name() const override;
+
+ size_t update_granularity() const override;
+
+ Key_Length_Specification key_spec() const override;
+
+ size_t default_nonce_length() const override;
+
+ bool valid_nonce_length(size_t n) const override;
+
+ void clear() override;
+
+ void reset() override;
+
+ protected:
+ ECB_Mode(BlockCipher* cipher, BlockCipherModePaddingMethod* padding);
+
+ const BlockCipher& cipher() const { return *m_cipher; }
+
+ const BlockCipherModePaddingMethod& padding() const { return *m_padding; }
+
+ private:
+ void start_msg(const byte nonce[], size_t nonce_len) override;
+ void key_schedule(const byte key[], size_t length) override;
+
+ std::unique_ptr<BlockCipher> m_cipher;
+ std::unique_ptr<BlockCipherModePaddingMethod> m_padding;
+ };
+
+/**
+* ECB Encryption
+*/
+class BOTAN_DLL ECB_Encryption final : public ECB_Mode
+ {
+ public:
+ /**
+ * @param cipher block cipher to use
+ * @param padding padding method to use
+ */
+ ECB_Encryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
+ ECB_Mode(cipher, padding) {}
+
+ size_t process(uint8_t buf[], size_t size) override;
+
+ void finish(secure_vector<byte>& final_block, size_t offset = 0) override;
+
+ size_t output_length(size_t input_length) const override;
+
+ size_t minimum_final_size() const override;
+ };
+
+/**
+* ECB Decryption
+*/
+class BOTAN_DLL ECB_Decryption final : public ECB_Mode
+ {
+ public:
+ /**
+ * @param cipher block cipher to use
+ * @param padding padding method to use
+ */
+ ECB_Decryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding) :
+ ECB_Mode(cipher, padding) {}
+
+ size_t process(uint8_t buf[], size_t size) override;
+
+ void finish(secure_vector<byte>& final_block, size_t offset = 0) override;
+
+ size_t output_length(size_t input_length) const override;
+
+ size_t minimum_final_size() const override;
+ };
+
+}
+
+#endif
+
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/Botan_rounding.h b/SoftHSMv2/src/lib/crypto/Botan_rounding.h
new file mode 100644
index 0000000..fbad3ae
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/Botan_rounding.h
@@ -0,0 +1,68 @@
+/*
+* Integer Rounding Functions
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_ROUNDING_H__
+#define BOTAN_ROUNDING_H__
+
+#include <botan/version.h>
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
+// ECB cipher mode was dropped in Botan 2.0.0
+// so including this code in SoftHSM for continued support
+// for e.g. CKA_VALUE_CHECK
+
+#include <botan/types.h>
+#include <botan/assert.h>
+
+namespace Botan {
+
+/**
+* Round up
+* @param n a non-negative integer
+* @param align_to the alignment boundary
+* @return n rounded up to a multiple of align_to
+*/
+inline size_t round_up(size_t n, size_t align_to)
+ {
+ BOTAN_ASSERT(align_to != 0, "align_to must not be 0");
+
+ if(n % align_to)
+ n += align_to - (n % align_to);
+ return n;
+ }
+
+/**
+* Round down
+* @param n an integer
+* @param align_to the alignment boundary
+* @return n rounded down to a multiple of align_to
+*/
+template<typename T>
+inline T round_down(T n, T align_to)
+ {
+ if(align_to == 0)
+ return n;
+
+ return (n - (n % align_to));
+ }
+
+/**
+* Clamp
+*/
+inline size_t clamp(size_t n, size_t lower_bound, size_t upper_bound)
+ {
+ if(n < lower_bound)
+ return lower_bound;
+ if(n > upper_bound)
+ return upper_bound;
+ return n;
+ }
+
+}
+
+#endif
+
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/CryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/CryptoFactory.cpp
new file mode 100644
index 0000000..c676676
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/CryptoFactory.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ CryptoFactory.cpp
+
+ This class is a factory for all cryptographic algorithm implementations. It
+ is an abstract base class for a factory that produces cryptographic library
+ specific implementations of cryptographic algorithms.
+ *****************************************************************************/
+
+#include "config.h"
+#include "CryptoFactory.h"
+
+#if defined(WITH_OPENSSL)
+
+#include "OSSLCryptoFactory.h"
+
+// Return the one-and-only instance
+CryptoFactory* CryptoFactory::i()
+{
+ return OSSLCryptoFactory::i();
+}
+
+// This will destroy the one-and-only instance.
+void CryptoFactory::reset()
+{
+ OSSLCryptoFactory::reset();
+}
+
+#elif defined(WITH_BOTAN)
+
+#include "BotanCryptoFactory.h"
+
+// Return the one-and-only instance
+CryptoFactory* CryptoFactory::i()
+{
+ return BotanCryptoFactory::i();
+}
+
+// This will destroy the one-and-only instance.
+void CryptoFactory::reset()
+{
+ BotanCryptoFactory::reset();
+}
+
+#else
+
+#error "You must configure a cryptographic library to use"
+
+#endif
+
+// Recycle a symmetric algorithm instance -- override this function in the derived
+// class if you need to perform specific clean-up
+void CryptoFactory::recycleSymmetricAlgorithm(SymmetricAlgorithm* toRecycle)
+{
+ delete toRecycle;
+}
+
+// Recycle an asymmetric algorithm instance -- override this function in the derived
+// class if you need to perform specific clean-up
+void CryptoFactory::recycleAsymmetricAlgorithm(AsymmetricAlgorithm* toRecycle)
+{
+ delete toRecycle;
+}
+
+// Recycle a hash algorithm instance -- override this function in the derived
+// class if you need to perform specific clean-up
+void CryptoFactory::recycleHashAlgorithm(HashAlgorithm* toRecycle)
+{
+ delete toRecycle;
+}
+
+// Recycle a MAC algorithm instance -- override this function in the derived
+// class if you need to perform specific clean-up
+void CryptoFactory::recycleMacAlgorithm(MacAlgorithm* toRecycle)
+{
+ delete toRecycle;
+}
diff --git a/SoftHSMv2/src/lib/crypto/CryptoFactory.h b/SoftHSMv2/src/lib/crypto/CryptoFactory.h
new file mode 100644
index 0000000..761e473
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/CryptoFactory.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ CryptoFactory.h
+
+ This class is a factory for all cryptographic algorithm implementations. It
+ is an abstract base class for a factory that produces cryptographic library
+ specific implementations of cryptographic algorithms.
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_CRYPTOFACTORY_H
+#define _SOFTHSM_V2_CRYPTOFACTORY_H
+
+#include "config.h"
+#include "SymmetricAlgorithm.h"
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+class CryptoFactory
+{
+public:
+ // Return the one-and-only instance
+ static CryptoFactory* i();
+
+ // This will destroy the one-and-only instance.
+ static void reset();
+
+#ifdef WITH_FIPS
+ // Return the FIPS 140-2 selftest status
+ virtual bool getFipsSelfTestStatus() const = 0;
+#endif
+
+ // Create a concrete instance of a symmetric algorithm
+ virtual SymmetricAlgorithm* getSymmetricAlgorithm(SymAlgo::Type algorithm) = 0;
+
+ // Recycle a symmetric algorithm instance -- override this function in the derived
+ // class if you need to perform specific clean-up
+ virtual void recycleSymmetricAlgorithm(SymmetricAlgorithm* toRecycle);
+
+ // Create a concrete instance of an asymmetric algorithm
+ virtual AsymmetricAlgorithm* getAsymmetricAlgorithm(AsymAlgo::Type algorithm) = 0;
+
+ // Recycle an asymmetric algorithm instance -- override this function in the derived
+ // class if you need to perform specific clean-up
+ virtual void recycleAsymmetricAlgorithm(AsymmetricAlgorithm* toRecycle);
+
+ // Create a concrete instance of a hash algorithm
+ virtual HashAlgorithm* getHashAlgorithm(HashAlgo::Type algorithm) = 0;
+
+ // Recycle a hash algorithm instance -- override this function in the derived
+ // class if you need to perform specific clean-up
+ virtual void recycleHashAlgorithm(HashAlgorithm* toRecycle);
+
+ // Create a concrete instance of a MAC algorithm
+ virtual MacAlgorithm* getMacAlgorithm(MacAlgo::Type algorithm) = 0;
+
+ // Recycle a MAC algorithm instance -- override this function in the derived
+ // class if you need to perform specific clean-up
+ virtual void recycleMacAlgorithm(MacAlgorithm* toRecycle);
+
+ // Get the global RNG (may be an unique RNG per thread)
+ virtual RNG* getRNG(RNGImpl::Type name = RNGImpl::Default) = 0;
+
+ // Destructor
+ virtual ~CryptoFactory() { }
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_CRYPTOFACTORY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DESKey.cpp b/SoftHSMv2/src/lib/crypto/DESKey.cpp
new file mode 100644
index 0000000..1d5f9bc
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DESKey.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DESKey.cpp
+
+ DES key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+#include "DESKey.h"
+#include "CryptoFactory.h"
+
+// Set the key
+bool DESKey::setKeyBits(const ByteString& keybits)
+{
+ if (bitLen > 0)
+ {
+ // Check if the correct input data is supplied
+ size_t expectedLen = 0;
+
+ switch(bitLen)
+ {
+ case 56:
+ expectedLen = 8;
+ break;
+ case 112:
+ expectedLen = 16;
+ break;
+ case 168:
+ expectedLen = 24;
+ break;
+ };
+
+ // Check the length
+ if (keybits.size() != expectedLen)
+ {
+ return false;
+ }
+ }
+
+ keyData = keybits;
+
+ return true;
+}
+
+// Get key check value
+ByteString DESKey::getKeyCheckValue() const
+{
+ SymAlgo::Type algo = SymAlgo::Unknown;
+ ByteString iv;
+ ByteString data;
+ ByteString encryptedData;
+ ByteString encryptedFinal;
+
+
+ switch (this->getBitLen())
+ {
+ case 56:
+ algo = SymAlgo::DES;
+ break;
+ case 112:
+ case 168:
+ algo = SymAlgo::DES3;
+ break;
+ default:
+ return encryptedData;
+ }
+
+ SymmetricAlgorithm* cipher = CryptoFactory::i()->getSymmetricAlgorithm(algo);
+ if (cipher == NULL) return encryptedData;
+
+ // Single block of null (0x00) bytes
+ data.resize(cipher->getBlockSize());
+ memset(&data[0], 0, data.size());
+
+ if (!cipher->encryptInit(this, SymMode::ECB, iv, false) ||
+ !cipher->encryptUpdate(data, encryptedData) ||
+ !cipher->encryptFinal(encryptedFinal))
+ {
+ CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
+ return encryptedData;
+ }
+ CryptoFactory::i()->recycleSymmetricAlgorithm(cipher);
+
+ encryptedData += encryptedFinal;
+ encryptedData.resize(3);
+
+ return encryptedData;
+}
diff --git a/SoftHSMv2/src/lib/crypto/DESKey.h b/SoftHSMv2/src/lib/crypto/DESKey.h
new file mode 100644
index 0000000..895e4fa
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DESKey.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DESKey.h
+
+ Base class for symmetric key classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DESKEY_H
+#define _SOFTHSM_V2_DESKEY_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+#include "SymmetricKey.h"
+
+class DESKey : public SymmetricKey
+{
+public:
+ // Base constructor
+ DESKey(size_t inBitLen = 0) : SymmetricKey(inBitLen) { }
+
+ // Set the key
+ virtual bool setKeyBits(const ByteString& keybits);
+
+ // Get the key check value
+ virtual ByteString getKeyCheckValue() const;
+};
+
+#endif // !_SOFTHSM_V2_DESKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DHParameters.cpp b/SoftHSMv2/src/lib/crypto/DHParameters.cpp
new file mode 100644
index 0000000..919901b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DHParameters.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHParameters.cpp
+
+ Diffie-Hellman parameters (only used for key generation)
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "DHParameters.h"
+#include <string.h>
+
+// The type
+/*static*/ const char* DHParameters::type = "Generic DH parameters";
+
+// Set the public prime p
+void DHParameters::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+// Set the generator g
+void DHParameters::setG(const ByteString& inG)
+{
+ g = inG;
+}
+
+// Set the optional bit length
+void DHParameters::setXBitLength(const size_t inBitLen)
+{
+ bitLen = inBitLen;
+}
+
+
+// Get the public prime p
+const ByteString& DHParameters::getP() const
+{
+ return p;
+}
+
+// Get the generator g
+const ByteString& DHParameters::getG() const
+{
+ return g;
+}
+
+// Get the optional bit length
+size_t DHParameters::getXBitLength() const
+{
+ return bitLen;
+}
+
+// Are the parameters of the given type?
+bool DHParameters::areOfType(const char* inType)
+{
+ return (strcmp(type, inType) == 0);
+}
+
+// Serialisation
+ByteString DHParameters::serialise() const
+{
+ ByteString len(bitLen);
+
+ return p.serialise() + g.serialise() + len.serialise();
+}
+
+bool DHParameters::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dG = ByteString::chainDeserialise(serialised);
+ ByteString dLen = ByteString::chainDeserialise(serialised);
+
+ if ((dP.size() == 0) ||
+ (dG.size() == 0) ||
+ (dLen.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setG(dG);
+ setXBitLength(dLen.long_val());
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/DHParameters.h b/SoftHSMv2/src/lib/crypto/DHParameters.h
new file mode 100644
index 0000000..e0c963f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DHParameters.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHParameters.h
+
+ Diffie-Hellman parameters (only used for key generation)
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DHPARAMETERS_H
+#define _SOFTHSM_V2_DHPARAMETERS_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "AsymmetricParameters.h"
+
+class DHParameters : public AsymmetricParameters
+{
+public:
+ // Base constructors
+ DHParameters() : bitLen(0) { }
+
+ // The type
+ static const char* type;
+
+ // Set the public prime p
+ void setP(const ByteString& inP);
+
+ // Set the generator g
+ void setG(const ByteString& inG);
+
+ // Set the optional bit length
+ void setXBitLength(const size_t inBitLen);
+
+ // Get the public prime p
+ const ByteString& getP() const;
+
+ // Get the generator g
+ const ByteString& getG() const;
+
+ // Get the optional bit length
+ size_t getXBitLength() const;
+
+ // Are the parameters of the given type?
+ virtual bool areOfType(const char* inType);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+private:
+ ByteString p;
+ ByteString g;
+ size_t bitLen;
+};
+
+#endif // !_SOFTHSM_V2_DHPARAMETERS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DHPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/DHPrivateKey.cpp
new file mode 100644
index 0000000..41103f1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DHPrivateKey.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHPrivateKey.cpp
+
+ Diffie-Hellman private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "DHPrivateKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* DHPrivateKey::type = "Abstract DH private key";
+
+// Check if the key is of the given type
+bool DHPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long DHPrivateKey::getBitLength() const
+{
+ return getP().bits();
+}
+
+// Get the output length
+unsigned long DHPrivateKey::getOutputLength() const
+{
+ return getP().size();
+}
+
+// Setters for the DH private key components
+void DHPrivateKey::setX(const ByteString& inX)
+{
+ x = inX;
+}
+
+// Setters for the DH public key components
+void DHPrivateKey::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+void DHPrivateKey::setG(const ByteString& inG)
+{
+ g = inG;
+}
+
+// Getters for the DH private key components
+const ByteString& DHPrivateKey::getX() const
+{
+ return x;
+}
+
+// Getters for the DH public key components
+const ByteString& DHPrivateKey::getP() const
+{
+ return p;
+}
+
+const ByteString& DHPrivateKey::getG() const
+{
+ return g;
+}
+
+// Serialisation
+ByteString DHPrivateKey::serialise() const
+{
+ return p.serialise() +
+ g.serialise() +
+ x.serialise();
+}
+
+bool DHPrivateKey::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dG = ByteString::chainDeserialise(serialised);
+ ByteString dX = ByteString::chainDeserialise(serialised);
+
+ if ((dP.size() == 0) ||
+ (dG.size() == 0) ||
+ (dX.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setG(dG);
+ setX(dX);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/DHPrivateKey.h b/SoftHSMv2/src/lib/crypto/DHPrivateKey.h
new file mode 100644
index 0000000..2c625da
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DHPrivateKey.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHPrivateKey.h
+
+ Diffie-Hellman private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DHPRIVATEKEY_H
+#define _SOFTHSM_V2_DHPRIVATEKEY_H
+
+#include "config.h"
+#include "PrivateKey.h"
+
+class DHPrivateKey : public PrivateKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the DH private key components
+ virtual void setX(const ByteString& inX);
+
+ // Setters for the DH public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setG(const ByteString& inG);
+
+ // Getters for the DH private key components
+ virtual const ByteString& getX() const;
+
+ // Getters for the DH public key components
+ virtual const ByteString& getP() const;
+ virtual const ByteString& getG() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Private components
+ ByteString x;
+
+ // Public components
+ ByteString p,g;
+};
+
+#endif // !_SOFTHSM_V2_DHPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DHPublicKey.cpp b/SoftHSMv2/src/lib/crypto/DHPublicKey.cpp
new file mode 100644
index 0000000..17e041d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DHPublicKey.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHPublicKey.cpp
+
+ Diffie-Hellman public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "DHPublicKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* DHPublicKey::type = "Abstract DH public key";
+
+// Check if the key is of the given type
+bool DHPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long DHPublicKey::getBitLength() const
+{
+ return getP().bits();
+}
+
+// Get the output length
+unsigned long DHPublicKey::getOutputLength() const
+{
+ return getP().size();
+}
+
+// Setters for the DH public key components
+void DHPublicKey::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+void DHPublicKey::setG(const ByteString& inG)
+{
+ g = inG;
+}
+
+void DHPublicKey::setY(const ByteString& inY)
+{
+ y = inY;
+}
+
+// Getters for the DH public key components
+const ByteString& DHPublicKey::getP() const
+{
+ return p;
+}
+
+const ByteString& DHPublicKey::getG() const
+{
+ return g;
+}
+
+const ByteString& DHPublicKey::getY() const
+{
+ return y;
+}
+
+// Serialisation
+ByteString DHPublicKey::serialise() const
+{
+ return p.serialise() +
+ g.serialise() +
+ y.serialise();
+}
+
+bool DHPublicKey::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dG = ByteString::chainDeserialise(serialised);
+ ByteString dY = ByteString::chainDeserialise(serialised);
+
+ if ((dP.size() == 0) ||
+ (dG.size() == 0) ||
+ (dY.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setG(dG);
+ setY(dY);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/DHPublicKey.h b/SoftHSMv2/src/lib/crypto/DHPublicKey.h
new file mode 100644
index 0000000..a070eb8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DHPublicKey.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHPublicKey.h
+
+ Diffie-Hellman public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DHPUBLICKEY_H
+#define _SOFTHSM_V2_DHPUBLICKEY_H
+
+#include "config.h"
+#include "PublicKey.h"
+
+class DHPublicKey : public PublicKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the DH public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setG(const ByteString& inG);
+ virtual void setY(const ByteString& inY);
+
+ // Getters for the DH public key components
+ virtual const ByteString& getP() const;
+ virtual const ByteString& getG() const;
+ virtual const ByteString& getY() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Public components
+ ByteString p,g,y;
+};
+
+#endif // !_SOFTHSM_V2_DHPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DSAParameters.cpp b/SoftHSMv2/src/lib/crypto/DSAParameters.cpp
new file mode 100644
index 0000000..79ef671
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DSAParameters.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSAParameters.cpp
+
+ DSA parameters (only used for key generation)
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "DSAParameters.h"
+#include <string.h>
+
+// The type
+/*static*/ const char* DSAParameters::type = "Generic DSA parameters";
+
+// Set the public prime p
+void DSAParameters::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+// Set the public subprime q
+void DSAParameters::setQ(const ByteString& inQ)
+{
+ q = inQ;
+}
+
+// Set the generator g
+void DSAParameters::setG(const ByteString& inG)
+{
+ g = inG;
+}
+
+// Get the public prime p
+const ByteString& DSAParameters::getP() const
+{
+ return p;
+}
+
+// Get the public subprime q
+const ByteString& DSAParameters::getQ() const
+{
+ return q;
+}
+
+// Get the generator g
+const ByteString& DSAParameters::getG() const
+{
+ return g;
+}
+
+// Are the parameters of the given type?
+bool DSAParameters::areOfType(const char* inType)
+{
+ return (strcmp(type, inType) == 0);
+}
+
+// Serialisation
+ByteString DSAParameters::serialise() const
+{
+ return p.serialise() + q.serialise() + g.serialise();
+}
+
+bool DSAParameters::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+ ByteString dG = ByteString::chainDeserialise(serialised);
+
+ if ((dP.size() == 0) ||
+ (dQ.size() == 0) ||
+ (dG.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setQ(dQ);
+ setG(dG);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/DSAParameters.h b/SoftHSMv2/src/lib/crypto/DSAParameters.h
new file mode 100644
index 0000000..978bc09
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DSAParameters.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSAParameters.h
+
+ DSA parameters (only used for key generation)
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DSAPARAMETERS_H
+#define _SOFTHSM_V2_DSAPARAMETERS_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "AsymmetricParameters.h"
+
+class DSAParameters : public AsymmetricParameters
+{
+public:
+ // The type
+ static const char* type;
+
+ // Set the public prime p
+ void setP(const ByteString& inP);
+
+ // Set the public subprime q
+ void setQ(const ByteString& inQ);
+
+ // Set the generator g
+ void setG(const ByteString& inG);
+
+ // Get the public prime p
+ const ByteString& getP() const;
+
+ // Get the public subprime q
+ const ByteString& getQ() const;
+
+ // Get the generator g
+ const ByteString& getG() const;
+
+ // Are the parameters of the given type?
+ virtual bool areOfType(const char* inType);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+private:
+ ByteString p;
+ ByteString q;
+ ByteString g;
+};
+
+#endif // !_SOFTHSM_V2_DSAPARAMETERS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/DSAPrivateKey.cpp
new file mode 100644
index 0000000..1bdfd2d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DSAPrivateKey.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSAPrivateKey.cpp
+
+ DSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "DSAPrivateKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* DSAPrivateKey::type = "Abstract DSA private key";
+
+// Check if the key is of the given type
+bool DSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long DSAPrivateKey::getBitLength() const
+{
+ return getP().bits();
+}
+
+// Get the output length
+unsigned long DSAPrivateKey::getOutputLength() const
+{
+ return getQ().size() * 2;
+}
+
+// Setters for the DSA private key components
+void DSAPrivateKey::setX(const ByteString& inX)
+{
+ x = inX;
+}
+
+// Setters for the DSA domain parameters
+void DSAPrivateKey::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+void DSAPrivateKey::setQ(const ByteString& inQ)
+{
+ q = inQ;
+}
+
+void DSAPrivateKey::setG(const ByteString& inG)
+{
+ g = inG;
+}
+
+// Getters for the DSA private key components
+const ByteString& DSAPrivateKey::getX() const
+{
+ return x;
+}
+
+// Getters for the DSA domain parameters
+const ByteString& DSAPrivateKey::getP() const
+{
+ return p;
+}
+
+const ByteString& DSAPrivateKey::getQ() const
+{
+ return q;
+}
+
+const ByteString& DSAPrivateKey::getG() const
+{
+ return g;
+}
+
+// Serialisation
+ByteString DSAPrivateKey::serialise() const
+{
+ return p.serialise() +
+ q.serialise() +
+ g.serialise() +
+ x.serialise();
+}
+
+bool DSAPrivateKey::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+ ByteString dG = ByteString::chainDeserialise(serialised);
+ ByteString dX = ByteString::chainDeserialise(serialised);
+
+ if ((dP.size() == 0) ||
+ (dQ.size() == 0) ||
+ (dG.size() == 0) ||
+ (dX.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setQ(dQ);
+ setG(dG);
+ setX(dX);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/DSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/DSAPrivateKey.h
new file mode 100644
index 0000000..3b2070f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DSAPrivateKey.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSAPrivateKey.h
+
+ DSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DSAPRIVATEKEY_H
+#define _SOFTHSM_V2_DSAPRIVATEKEY_H
+
+#include "config.h"
+#include "PrivateKey.h"
+
+class DSAPrivateKey : public PrivateKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the DSA private key components
+ virtual void setX(const ByteString& inX);
+
+ // Setters for the DSA domain parameters
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setG(const ByteString& inG);
+
+ // Getters for the DSA private key components
+ virtual const ByteString& getX() const;
+
+ // Getters for the DSA domain parameters
+ virtual const ByteString& getP() const;
+ virtual const ByteString& getQ() const;
+ virtual const ByteString& getG() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Private components
+ ByteString x;
+
+ // Domain parameters
+ ByteString p,q,g;
+};
+
+#endif // !_SOFTHSM_V2_DSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/DSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/DSAPublicKey.cpp
new file mode 100644
index 0000000..4439bdd
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DSAPublicKey.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSAPublicKey.cpp
+
+ DSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "DSAPublicKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* DSAPublicKey::type = "Abstract DSA public key";
+
+// Check if the key is of the given type
+bool DSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long DSAPublicKey::getBitLength() const
+{
+ return getP().bits();
+}
+
+// Get the output length
+unsigned long DSAPublicKey::getOutputLength() const
+{
+ return getQ().size() * 2;
+}
+
+// Setters for the DSA public key components
+void DSAPublicKey::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+void DSAPublicKey::setQ(const ByteString& inQ)
+{
+ q = inQ;
+}
+
+void DSAPublicKey::setG(const ByteString& inG)
+{
+ g = inG;
+}
+
+void DSAPublicKey::setY(const ByteString& inY)
+{
+ y = inY;
+}
+
+// Getters for the DSA public key components
+const ByteString& DSAPublicKey::getP() const
+{
+ return p;
+}
+
+const ByteString& DSAPublicKey::getQ() const
+{
+ return q;
+}
+
+const ByteString& DSAPublicKey::getG() const
+{
+ return g;
+}
+
+const ByteString& DSAPublicKey::getY() const
+{
+ return y;
+}
+
+// Serialisation
+ByteString DSAPublicKey::serialise() const
+{
+ return p.serialise() +
+ q.serialise() +
+ g.serialise() +
+ y.serialise();
+}
+
+bool DSAPublicKey::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+ ByteString dG = ByteString::chainDeserialise(serialised);
+ ByteString dY = ByteString::chainDeserialise(serialised);
+
+ if ((dP.size() == 0) ||
+ (dQ.size() == 0) ||
+ (dG.size() == 0) ||
+ (dY.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setQ(dQ);
+ setG(dG);
+ setY(dY);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/DSAPublicKey.h b/SoftHSMv2/src/lib/crypto/DSAPublicKey.h
new file mode 100644
index 0000000..6d41e5d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/DSAPublicKey.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSAPublicKey.h
+
+ DSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DSAPUBLICKEY_H
+#define _SOFTHSM_V2_DSAPUBLICKEY_H
+
+#include "config.h"
+#include "PublicKey.h"
+
+class DSAPublicKey : public PublicKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the DSA public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setG(const ByteString& inG);
+ virtual void setY(const ByteString& inY);
+
+ // Getters for the DSA public key components
+ virtual const ByteString& getP() const;
+ virtual const ByteString& getQ() const;
+ virtual const ByteString& getG() const;
+ virtual const ByteString& getY() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Public components
+ ByteString p,q,g,y;
+};
+
+#endif // !_SOFTHSM_V2_DSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/ECParameters.cpp b/SoftHSMv2/src/lib/crypto/ECParameters.cpp
new file mode 100644
index 0000000..c4a6cfa
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/ECParameters.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECParameters.cpp
+
+ Elliptic Curve parameters (only used for key generation)
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "ECParameters.h"
+#include <string.h>
+
+// The type
+/*static*/ const char* ECParameters::type = "Generic EC parameters";
+
+// Set the curve OID ec
+void ECParameters::setEC(const ByteString& inEC)
+{
+ ec = inEC;
+}
+
+// Get the curve OID ec
+const ByteString& ECParameters::getEC() const
+{
+ return ec;
+}
+
+// Are the parameters of the given type?
+bool ECParameters::areOfType(const char* inType)
+{
+ return (strcmp(type, inType) == 0);
+}
+
+// Serialisation
+ByteString ECParameters::serialise() const
+{
+ return ec.serialise();
+}
+
+bool ECParameters::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+
+ if (dEC.size() == 0)
+ {
+ return false;
+ }
+
+ setEC(dEC);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/ECParameters.h b/SoftHSMv2/src/lib/crypto/ECParameters.h
new file mode 100644
index 0000000..76ca3e8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/ECParameters.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECParameters.h
+
+ Elliptic Curve parameters (only used for key generation)
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECPARAMETERS_H
+#define _SOFTHSM_V2_ECPARAMETERS_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "AsymmetricParameters.h"
+
+class ECParameters : public AsymmetricParameters
+{
+public:
+ // The type
+ static const char* type;
+
+ // Set the curve OID ec
+ void setEC(const ByteString& inEC);
+
+ // Get the curve OID ec
+ const ByteString& getEC() const;
+
+ // Are the parameters of the given type?
+ virtual bool areOfType(const char* inType);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+private:
+ ByteString ec;
+};
+
+#endif // !_SOFTHSM_V2_ECPARAMETERS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/ECPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/ECPrivateKey.cpp
new file mode 100644
index 0000000..f132f2e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/ECPrivateKey.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECPrivateKey.cpp
+
+ Elliptic Curve private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "ECPrivateKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* ECPrivateKey::type = "Abstract EC private key";
+
+// Check if the key is of the given type
+bool ECPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long ECPrivateKey::getBitLength() const
+{
+ return getD().bits();
+}
+
+// Get the output length
+unsigned long ECPrivateKey::getOutputLength() const
+{
+ return getOrderLength() * 2;
+}
+
+// Setters for the EC private key components
+void ECPrivateKey::setD(const ByteString& inD)
+{
+ d = inD;
+}
+
+// Setters for the EC public key components
+void ECPrivateKey::setEC(const ByteString& inEC)
+{
+ ec = inEC;
+}
+
+// Getters for the EC private key components
+const ByteString& ECPrivateKey::getD() const
+{
+ return d;
+}
+
+// Getters for the EC public key components
+const ByteString& ECPrivateKey::getEC() const
+{
+ return ec;
+}
+
+// Serialisation
+ByteString ECPrivateKey::serialise() const
+{
+ return ec.serialise() +
+ d.serialise();
+}
+
+bool ECPrivateKey::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+ ByteString dD = ByteString::chainDeserialise(serialised);
+
+ if ((dEC.size() == 0) ||
+ (dD.size() == 0))
+ {
+ return false;
+ }
+
+ setEC(dEC);
+ setD(dD);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/ECPrivateKey.h b/SoftHSMv2/src/lib/crypto/ECPrivateKey.h
new file mode 100644
index 0000000..0814181
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/ECPrivateKey.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECPrivateKey.h
+
+ Elliptic Curve private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECPRIVATEKEY_H
+#define _SOFTHSM_V2_ECPRIVATEKEY_H
+
+#include "config.h"
+#include "PrivateKey.h"
+
+class ECPrivateKey : public PrivateKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const = 0;
+
+ // Setters for the EC private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the EC public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Getters for the EC private key components
+ virtual const ByteString& getD() const;
+
+ // Getters for the EC public key components
+ virtual const ByteString& getEC() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Private components
+ ByteString d;
+
+ // Public components
+ ByteString ec;
+};
+
+#endif // !_SOFTHSM_V2_ECPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/ECPublicKey.cpp b/SoftHSMv2/src/lib/crypto/ECPublicKey.cpp
new file mode 100644
index 0000000..a92d137
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/ECPublicKey.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECPublicKey.cpp
+
+ Elliptic Curve public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "ECPublicKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* ECPublicKey::type = "Abstract EC public key";
+
+// Check if the key is of the given type
+bool ECPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long ECPublicKey::getBitLength() const
+{
+ return getQ().size() * 8;
+}
+
+// Get the output length
+unsigned long ECPublicKey::getOutputLength() const
+{
+ return getOrderLength() * 2;
+}
+
+// Setters for the EC public key components
+void ECPublicKey::setEC(const ByteString& inEC)
+{
+ ec = inEC;
+}
+
+void ECPublicKey::setQ(const ByteString& inQ)
+{
+ q = inQ;
+}
+
+// Getters for the EC public key components
+const ByteString& ECPublicKey::getEC() const
+{
+ return ec;
+}
+
+const ByteString& ECPublicKey::getQ() const
+{
+ return q;
+}
+
+// Serialisation
+ByteString ECPublicKey::serialise() const
+{
+ return ec.serialise() +
+ q.serialise();
+}
+
+bool ECPublicKey::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+
+ if ((dEC.size() == 0) ||
+ (dQ.size() == 0))
+ {
+ return false;
+ }
+
+ setEC(dEC);
+ setQ(dQ);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/ECPublicKey.h b/SoftHSMv2/src/lib/crypto/ECPublicKey.h
new file mode 100644
index 0000000..ce6cf63
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/ECPublicKey.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECPublicKey.h
+
+ Elliptic Curve public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECPUBLICKEY_H
+#define _SOFTHSM_V2_ECPUBLICKEY_H
+
+#include "config.h"
+#include "PublicKey.h"
+
+class ECPublicKey : public PublicKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const = 0;
+
+ // Setters for the EC public key components
+ virtual void setEC(const ByteString& inEc);
+ virtual void setQ(const ByteString& inQ);
+
+ // Getters for the EC public key components
+ virtual const ByteString& getEC() const;
+ virtual const ByteString& getQ() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Public components
+ ByteString ec,q;
+};
+
+#endif // !_SOFTHSM_V2_ECPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/GOSTPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/GOSTPrivateKey.cpp
new file mode 100644
index 0000000..9d23855
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/GOSTPrivateKey.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTPrivateKey.cpp
+
+ GOST R 34.10-2001 private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "GOSTPrivateKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* GOSTPrivateKey::type = "Abstract GOST private key";
+
+// Check if the key is of the given type
+bool GOSTPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long GOSTPrivateKey::getBitLength() const
+{
+ return getD().bits();
+}
+
+// Setters for the GOST private key components
+void GOSTPrivateKey::setD(const ByteString& inD)
+{
+ d = inD;
+}
+
+// Setters for the GOST public key components
+void GOSTPrivateKey::setEC(const ByteString& inEC)
+{
+ ec = inEC;
+}
+
+// Getters for the GOST private key components
+const ByteString& GOSTPrivateKey::getD() const
+{
+ return d;
+}
+
+// Getters for the GOST public key components
+const ByteString& GOSTPrivateKey::getEC() const
+{
+ return ec;
+}
diff --git a/SoftHSMv2/src/lib/crypto/GOSTPrivateKey.h b/SoftHSMv2/src/lib/crypto/GOSTPrivateKey.h
new file mode 100644
index 0000000..929ddb1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/GOSTPrivateKey.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTPrivateKey.h
+
+ GOST R 34.10-2001 private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_GOSTPRIVATEKEY_H
+#define _SOFTHSM_V2_GOSTPRIVATEKEY_H
+
+#include "config.h"
+#include "PrivateKey.h"
+
+class GOSTPrivateKey : public PrivateKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const = 0;
+
+ // Setters for the GOST private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the GOST public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Getters for the GOST private key components
+ virtual const ByteString& getD() const;
+
+ // Getters for the GOST public key components
+ virtual const ByteString& getEC() const;
+
+ // Serialisation
+ virtual ByteString serialise() const = 0;
+ virtual bool deserialise(ByteString& serialised) = 0;
+
+protected:
+ // Private components
+ ByteString d;
+
+ // Public components
+ ByteString ec;
+};
+
+#endif // !_SOFTHSM_V2_GOSTPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/GOSTPublicKey.cpp b/SoftHSMv2/src/lib/crypto/GOSTPublicKey.cpp
new file mode 100644
index 0000000..ad94068
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/GOSTPublicKey.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTPublicKey.cpp
+
+ GOST R 34.10-2001 public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "GOSTPublicKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* GOSTPublicKey::type = "Abstract GOST public key";
+
+// Check if the key is of the given type
+bool GOSTPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long GOSTPublicKey::getBitLength() const
+{
+ return getQ().size() * 8;
+}
+
+// Setters for the GOST public key components
+void GOSTPublicKey::setQ(const ByteString& inQ)
+{
+ q = inQ;
+}
+
+// Setters for the GOST public key components
+void GOSTPublicKey::setEC(const ByteString& inEC)
+{
+ ec = inEC;
+}
+
+// Getters for the GOST public key components
+const ByteString& GOSTPublicKey::getQ() const
+{
+ return q;
+}
+
+// Getters for the GOST public key components
+const ByteString& GOSTPublicKey::getEC() const
+{
+ return ec;
+}
diff --git a/SoftHSMv2/src/lib/crypto/GOSTPublicKey.h b/SoftHSMv2/src/lib/crypto/GOSTPublicKey.h
new file mode 100644
index 0000000..28de7b8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/GOSTPublicKey.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTPublicKey.h
+
+ GOST R 34.10-2001 public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_GOSTPUBLICKEY_H
+#define _SOFTHSM_V2_GOSTPUBLICKEY_H
+
+#include "config.h"
+#include "PublicKey.h"
+
+class GOSTPublicKey : public PublicKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const = 0;
+
+ // Setters for the GOST public key components
+ virtual void setQ(const ByteString& inQ);
+ virtual void setEC(const ByteString& inEC);
+
+ // Getters for the GOST public key components
+ virtual const ByteString& getQ() const;
+ virtual const ByteString& getEC() const;
+
+ // Serialisation
+ virtual ByteString serialise() const = 0;
+ virtual bool deserialise(ByteString& serialised) = 0;
+
+protected:
+ // Public components
+ ByteString q, ec;
+};
+
+#endif // !_SOFTHSM_V2_GOSTPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/HashAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/HashAlgorithm.cpp
new file mode 100644
index 0000000..934a64c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/HashAlgorithm.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ HashAlgorithm.cpp
+
+ Base class for hash algorithm classes
+ *****************************************************************************/
+
+#include "config.h"
+#include "HashAlgorithm.h"
+
+// Base constructor
+HashAlgorithm::HashAlgorithm()
+{
+ currentOperation = NONE;
+}
+
+// Hashing functions
+bool HashAlgorithm::hashInit()
+{
+ if (currentOperation != NONE)
+ {
+ return false;
+ }
+
+ currentOperation = HASHING;
+
+ return true;
+}
+
+bool HashAlgorithm::hashUpdate(const ByteString& /*data*/)
+{
+ if (currentOperation != HASHING)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool HashAlgorithm::hashFinal(ByteString& /*hashedData*/)
+{
+ if (currentOperation != HASHING)
+ {
+ return false;
+ }
+
+ currentOperation = NONE;
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/HashAlgorithm.h b/SoftHSMv2/src/lib/crypto/HashAlgorithm.h
new file mode 100644
index 0000000..ca2ae08
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/HashAlgorithm.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ HashAlgorithm.h
+
+ Base class for hash algorithm classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_HASHALGORITHM_H
+#define _SOFTHSM_V2_HASHALGORITHM_H
+
+#include "config.h"
+#include "ByteString.h"
+
+struct HashAlgo
+{
+ enum Type
+ {
+ Unknown,
+ MD5,
+ SHA1,
+ SHA224,
+ SHA256,
+ SHA384,
+ SHA512,
+ GOST
+ };
+};
+
+class HashAlgorithm
+{
+public:
+ // Base constructors
+ HashAlgorithm();
+
+ // Destructor
+ virtual ~HashAlgorithm() { }
+
+ // Hashing functions
+ virtual bool hashInit();
+ virtual bool hashUpdate(const ByteString& data);
+ virtual bool hashFinal(ByteString& hashedData);
+
+ virtual int getHashSize() = 0;
+protected:
+ // The current operation
+ enum
+ {
+ NONE,
+ HASHING
+ }
+ currentOperation;
+};
+
+#endif // !_SOFTHSM_V2_HASHALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/MacAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/MacAlgorithm.cpp
new file mode 100644
index 0000000..e100dc1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/MacAlgorithm.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ MacAlgorithm.cpp
+
+ Base class for MAC algorithm classes
+ *****************************************************************************/
+
+#include "MacAlgorithm.h"
+#include <algorithm>
+#include <string.h>
+
+MacAlgorithm::MacAlgorithm()
+{
+ currentOperation = NONE;
+ currentKey = NULL;
+}
+
+bool MacAlgorithm::signInit(const SymmetricKey* key)
+{
+ if ((key == NULL) || (currentOperation != NONE))
+ {
+ return false;
+ }
+
+ currentKey = key;
+ currentOperation = SIGN;
+
+ return true;
+}
+
+bool MacAlgorithm::signUpdate(const ByteString& /*dataToSign*/)
+{
+ if (currentOperation != SIGN)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool MacAlgorithm::signFinal(ByteString& /*signature*/)
+{
+ if (currentOperation != SIGN)
+ {
+ return false;
+ }
+
+ currentOperation = NONE;
+ currentKey = NULL;
+
+ return true;
+}
+
+bool MacAlgorithm::verifyInit(const SymmetricKey* key)
+{
+ if ((key == NULL) || (currentOperation != NONE))
+ {
+ return false;
+ }
+
+ currentOperation = VERIFY;
+ currentKey = key;
+
+ return true;
+}
+
+bool MacAlgorithm::verifyUpdate(const ByteString& /*originalData*/)
+{
+ if (currentOperation != VERIFY)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool MacAlgorithm::verifyFinal(ByteString& /*signature*/)
+{
+ if (currentOperation != VERIFY)
+ {
+ return false;
+ }
+
+ currentOperation = NONE;
+ currentKey = NULL;
+
+ return true;
+}
+
+unsigned long MacAlgorithm::getMinKeySize()
+{
+ return 0;
+}
+
+unsigned long MacAlgorithm::getMaxKeySize()
+{
+ return 0;
+}
+
+void MacAlgorithm::recycleKey(SymmetricKey* toRecycle)
+{
+ delete toRecycle;
+}
diff --git a/SoftHSMv2/src/lib/crypto/MacAlgorithm.h b/SoftHSMv2/src/lib/crypto/MacAlgorithm.h
new file mode 100644
index 0000000..e9b22b0
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/MacAlgorithm.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ MacAlgorithm.h
+
+ Base class for MAC algorithm classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_MACALGORITHM_H
+#define _SOFTHSM_V2_MACALGORITHM_H
+
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "RNG.h"
+
+struct MacAlgo
+{
+ enum Type
+ {
+ Unknown,
+ HMAC_MD5,
+ HMAC_SHA1,
+ HMAC_SHA224,
+ HMAC_SHA256,
+ HMAC_SHA384,
+ HMAC_SHA512,
+ HMAC_GOST,
+ CMAC_DES,
+ CMAC_AES
+ };
+};
+
+class MacAlgorithm
+{
+public:
+ // Base constructors
+ MacAlgorithm();
+
+ // Destructor
+ virtual ~MacAlgorithm() { }
+
+ // Signing functions
+ virtual bool signInit(const SymmetricKey* key);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(const SymmetricKey* key);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(ByteString& signature);
+
+ // Key
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual void recycleKey(SymmetricKey* toRecycle);
+
+ // Return the MAC size
+ virtual size_t getMacSize() const = 0;
+
+protected:
+ // The current key
+ const SymmetricKey* currentKey;
+
+private:
+ // The current operation
+ enum
+ {
+ NONE,
+ SIGN,
+ VERIFY
+ }
+ currentOperation;
+};
+
+#endif // !_SOFTHSM_V2_MACALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/Makefile.am b/SoftHSMv2/src/lib/crypto/Makefile.am
new file mode 100644
index 0000000..f65e0a4
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/Makefile.am
@@ -0,0 +1,126 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(srcdir)/.. \
+ -I$(srcdir)/../common \
+ -I$(srcdir)/../data_mgr \
+ -I$(srcdir)/../pkcs11 \
+ @CRYPTO_INCLUDES@
+
+noinst_LTLIBRARIES = libsofthsm_crypto.la
+libsofthsm_crypto_la_SOURCES = AESKey.cpp \
+ AsymmetricAlgorithm.cpp \
+ AsymmetricKeyPair.cpp \
+ CryptoFactory.cpp \
+ DESKey.cpp \
+ DHParameters.cpp \
+ DHPublicKey.cpp \
+ DHPrivateKey.cpp \
+ DSAParameters.cpp \
+ DSAPublicKey.cpp \
+ DSAPrivateKey.cpp \
+ ECParameters.cpp \
+ ECPublicKey.cpp \
+ ECPrivateKey.cpp \
+ GOSTPublicKey.cpp \
+ GOSTPrivateKey.cpp \
+ HashAlgorithm.cpp \
+ MacAlgorithm.cpp \
+ RSAParameters.cpp \
+ RSAPrivateKey.cpp \
+ RSAPublicKey.cpp \
+ SymmetricAlgorithm.cpp \
+ SymmetricKey.cpp
+libsofthsm_crypto_la_LIBADD = @CRYPTO_LIBS@
+
+SUBDIRS = test
+
+EXTRA_DIST = $(srcdir)/*.h $(srcdir)/*.cpp
+
+# Compile with support of OpenSSL
+if WITH_OPENSSL
+libsofthsm_crypto_la_SOURCES += OSSLAES.cpp \
+ OSSLComp.cpp \
+ OSSLCryptoFactory.cpp \
+ OSSLDES.cpp \
+ OSSLDH.cpp \
+ OSSLDHKeyPair.cpp \
+ OSSLDHPrivateKey.cpp \
+ OSSLDHPublicKey.cpp \
+ OSSLDSA.cpp \
+ OSSLDSAKeyPair.cpp \
+ OSSLDSAPrivateKey.cpp \
+ OSSLDSAPublicKey.cpp \
+ OSSLECDH.cpp \
+ OSSLECDSA.cpp \
+ OSSLECKeyPair.cpp \
+ OSSLECPrivateKey.cpp \
+ OSSLECPublicKey.cpp \
+ OSSLEVPHashAlgorithm.cpp \
+ OSSLEVPMacAlgorithm.cpp \
+ OSSLEVPCMacAlgorithm.cpp \
+ OSSLEVPSymmetricAlgorithm.cpp \
+ OSSLGOST.cpp \
+ OSSLGOSTKeyPair.cpp \
+ OSSLGOSTPrivateKey.cpp \
+ OSSLGOSTPublicKey.cpp \
+ OSSLGOSTR3411.cpp \
+ OSSLCMAC.cpp \
+ OSSLHMAC.cpp \
+ OSSLMD5.cpp \
+ OSSLRNG.cpp \
+ OSSLRSA.cpp \
+ OSSLRSAKeyPair.cpp \
+ OSSLRSAPrivateKey.cpp \
+ OSSLRSAPublicKey.cpp \
+ OSSLSHA1.cpp \
+ OSSLSHA224.cpp \
+ OSSLSHA256.cpp \
+ OSSLSHA384.cpp \
+ OSSLSHA512.cpp \
+ OSSLUtil.cpp
+endif
+
+# Compile with support of Botan
+if WITH_BOTAN
+libsofthsm_crypto_la_SOURCES += BotanAES.cpp \
+ BotanCryptoFactory.cpp \
+ BotanDES.cpp \
+ BotanDH.cpp \
+ BotanDHKeyPair.cpp \
+ BotanDHPrivateKey.cpp \
+ BotanDHPublicKey.cpp \
+ BotanDSA.cpp \
+ BotanDSAKeyPair.cpp \
+ BotanDSAPrivateKey.cpp \
+ BotanDSAPublicKey.cpp \
+ BotanECDH.cpp \
+ BotanECDHKeyPair.cpp \
+ BotanECDHPrivateKey.cpp \
+ BotanECDHPublicKey.cpp \
+ BotanECDSA.cpp \
+ BotanECDSAKeyPair.cpp \
+ BotanECDSAPrivateKey.cpp \
+ BotanECDSAPublicKey.cpp \
+ BotanGOST.cpp \
+ BotanGOSTKeyPair.cpp \
+ BotanGOSTPrivateKey.cpp \
+ BotanGOSTPublicKey.cpp \
+ BotanGOSTR3411.cpp \
+ BotanHashAlgorithm.cpp \
+ BotanMAC.cpp \
+ BotanMacAlgorithm.cpp \
+ BotanMD5.cpp \
+ BotanRNG.cpp \
+ BotanRSA.cpp \
+ BotanRSAKeyPair.cpp \
+ BotanRSAPrivateKey.cpp \
+ BotanRSAPublicKey.cpp \
+ BotanSHA1.cpp \
+ BotanSHA224.cpp \
+ BotanSHA256.cpp \
+ BotanSHA384.cpp \
+ BotanSHA512.cpp \
+ BotanSymmetricAlgorithm.cpp \
+ BotanUtil.cpp \
+ Botan_ecb.cpp
+endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLAES.cpp b/SoftHSMv2/src/lib/crypto/OSSLAES.cpp
new file mode 100644
index 0000000..fd92a3e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLAES.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLAES.cpp
+
+ OpenSSL AES implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLAES.h"
+#include <algorithm>
+#include <openssl/aes.h>
+#include "salloc.h"
+
+// Wrap/Unwrap keys
+#ifdef HAVE_AES_KEY_WRAP
+bool OSSLAES::wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out)
+{
+ // RFC 3394 input length checks do not apply to RFC 5649 mode with padding
+ if (mode == SymWrap::AES_KEYWRAP && !checkLength(in.size(), 16, "wrap"))
+ return false;
+
+ return wrapUnwrapKey(key, mode, in, out, 1);
+}
+#else
+bool OSSLAES::wrapKey(const SymmetricKey* /*key*/, const SymWrap::Type /*mode*/, const ByteString& /*in*/, ByteString& /*out*/)
+{
+ return false;
+}
+#endif
+
+#ifdef HAVE_AES_KEY_WRAP
+bool OSSLAES::unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out)
+{
+ // RFC 3394 algorithm produce at least 3 blocks of data
+ if ((mode == SymWrap::AES_KEYWRAP && !checkLength(in.size(), 24, "unwrap")) ||
+ // RFC 5649 algorithm produce at least 2 blocks of data
+ (mode == SymWrap::AES_KEYWRAP_PAD && !checkLength(in.size(), 16, "unwrap")))
+ return false;
+ return wrapUnwrapKey(key, mode, in, out, 0);
+}
+#else
+bool OSSLAES::unwrapKey(const SymmetricKey* /*key*/, const SymWrap::Type /*mode*/, const ByteString& /*in*/, ByteString& /*out*/)
+{
+ return false;
+}
+#endif
+
+#ifdef HAVE_AES_KEY_WRAP
+// RFC 3394 wrapping and all unwrapping algorithms require aligned blocks
+bool OSSLAES::checkLength(const int insize, const int minsize, const char * const operation) const
+{
+ if (insize < minsize)
+ {
+ ERROR_MSG("key data to %s too small", operation);
+ return false;
+ }
+ if ((insize % 8) != 0)
+ {
+ ERROR_MSG("key data to %s not aligned", operation);
+ return false;
+ }
+ return true;
+}
+
+const EVP_CIPHER* OSSLAES::getWrapCipher(const SymWrap::Type mode, const SymmetricKey* key) const
+{
+ if (key == NULL)
+ return NULL;
+
+ // Check currentKey bit length; AES only supports 128, 192 or 256 bit keys
+ if ((key->getBitLen() != 128) &&
+ (key->getBitLen() != 192) &&
+ (key->getBitLen() != 256))
+ {
+ ERROR_MSG("Invalid AES key length (%d bits)", key->getBitLen());
+
+ return NULL;
+ }
+
+#ifdef HAVE_AES_KEY_WRAP
+ // Determine the un/wrapping mode
+ if (mode == SymWrap::AES_KEYWRAP)
+ {
+ // RFC 3394 AES key wrap
+ switch(key->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_wrap();
+ case 192:
+ return EVP_aes_192_wrap();
+ case 256:
+ return EVP_aes_256_wrap();
+ };
+ }
+#endif
+#ifdef HAVE_AES_KEY_WRAP_PAD
+ if (mode == SymWrap::AES_KEYWRAP_PAD)
+ {
+ // RFC 5649 AES key wrap with pad
+ switch(key->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_wrap_pad();
+ case 192:
+ return EVP_aes_192_wrap_pad();
+ case 256:
+ return EVP_aes_256_wrap_pad();
+ };
+ }
+#endif
+
+ ERROR_MSG("unknown AES key wrap mode %i", mode);
+ return NULL;
+}
+
+// EVP wrapping/unwrapping
+// wrap = 1 -> wrapping
+// wrap = 0 -> unwrapping
+bool OSSLAES::wrapUnwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out, const int wrap) const
+{
+ const char *prefix = "";
+ if (wrap == 0)
+ prefix = "un";
+
+ // Determine the cipher method
+ const EVP_CIPHER* cipher = getWrapCipher(mode, key);
+ if (cipher == NULL)
+ {
+ ERROR_MSG("Failed to get EVP %swrap cipher", prefix);
+ return false;
+ }
+
+ // Allocate the EVP context
+ EVP_CIPHER_CTX* pWrapCTX = EVP_CIPHER_CTX_new();
+ if (pWrapCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for EVP_CIPHER_CTX");
+ return false;
+ }
+ EVP_CIPHER_CTX_set_flags(pWrapCTX, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+
+ int rv = EVP_CipherInit_ex(pWrapCTX, cipher, NULL, (unsigned char*) key->getKeyBits().const_byte_str(), NULL, wrap);
+ if (rv)
+ // Padding is handled by cipher mode separately
+ rv = EVP_CIPHER_CTX_set_padding(pWrapCTX, 0);
+ if (!rv)
+ {
+ ERROR_MSG("Failed to initialise EVP cipher %swrap operation", prefix);
+
+ EVP_CIPHER_CTX_free(pWrapCTX);
+ return false;
+ }
+
+ // 1 input byte could be expanded to two AES blocks
+ out.resize(in.size() + 2 * EVP_CIPHER_CTX_block_size(pWrapCTX) - 1);
+ int outLen = 0;
+ int curBlockLen = 0;
+ rv = EVP_CipherUpdate(pWrapCTX, &out[0], &curBlockLen, in.const_byte_str(), in.size());
+ if (rv == 1) {
+ outLen = curBlockLen;
+ rv = EVP_CipherFinal_ex(pWrapCTX, &out[0] + outLen, &curBlockLen);
+ }
+ if (rv != 1)
+ {
+ ERROR_MSG("Failed EVP %swrap operation", prefix);
+
+ EVP_CIPHER_CTX_free(pWrapCTX);
+ return false;
+ }
+ EVP_CIPHER_CTX_free(pWrapCTX);
+ outLen += curBlockLen;
+ out.resize(outLen);
+ return true;
+}
+#endif
+
+const EVP_CIPHER* OSSLAES::getCipher() const
+{
+ if (currentKey == NULL) return NULL;
+
+ // Check currentKey bit length; AES only supports 128, 192 or 256 bit keys
+ if ((currentKey->getBitLen() != 128) &&
+ (currentKey->getBitLen() != 192) &&
+ (currentKey->getBitLen() != 256))
+ {
+ ERROR_MSG("Invalid AES currentKey length (%d bits)", currentKey->getBitLen());
+
+ return NULL;
+ }
+
+ // Determine the cipher mode
+ if (currentCipherMode == SymMode::CBC)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_cbc();
+ case 192:
+ return EVP_aes_192_cbc();
+ case 256:
+ return EVP_aes_256_cbc();
+ };
+ }
+ else if (currentCipherMode == SymMode::ECB)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_ecb();
+ case 192:
+ return EVP_aes_192_ecb();
+ case 256:
+ return EVP_aes_256_ecb();
+ };
+ }
+ else if (currentCipherMode == SymMode::CTR)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_ctr();
+ case 192:
+ return EVP_aes_192_ctr();
+ case 256:
+ return EVP_aes_256_ctr();
+ };
+ }
+ else if (currentCipherMode == SymMode::GCM)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_gcm();
+ case 192:
+ return EVP_aes_192_gcm();
+ case 256:
+ return EVP_aes_256_gcm();
+ };
+ }
+
+ ERROR_MSG("Invalid AES cipher mode %i", currentCipherMode);
+
+ return NULL;
+}
+
+size_t OSSLAES::getBlockSize() const
+{
+ // The block size is 128 bits
+ return 128 >> 3;
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLAES.h b/SoftHSMv2/src/lib/crypto/OSSLAES.h
new file mode 100644
index 0000000..6310f31
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLAES.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLAES.h
+
+ OpenSSL AES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLAES_H
+#define _SOFTHSM_V2_OSSLAES_H
+
+#include <openssl/evp.h>
+#include <string>
+#include "config.h"
+#include "OSSLEVPSymmetricAlgorithm.h"
+
+class OSSLAES : public OSSLEVPSymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~OSSLAES() { }
+
+ // Wrap/Unwrap keys
+ virtual bool wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ virtual bool unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ // Return the block size
+ virtual size_t getBlockSize() const;
+
+protected:
+ // Return the right EVP cipher for the operation
+ virtual const EVP_CIPHER* getCipher() const;
+ const EVP_CIPHER* getWrapCipher(const SymWrap::Type mode, const SymmetricKey* key) const;
+ bool wrapUnwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out, const int wrap) const;
+ bool checkLength(const int insize, const int minsize, const char * const operation) const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLAES_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLCMAC.cpp b/SoftHSMv2/src/lib/crypto/OSSLCMAC.cpp
new file mode 100644
index 0000000..554c308
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLCMAC.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLHMAC.cpp
+
+ OpenSSL HMAC implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLCMAC.h"
+
+const EVP_CIPHER* OSSLCMACDES::getEVPCipher() const
+{
+ switch(currentKey->getBitLen())
+ {
+ case 56:
+ ERROR_MSG("Only supporting 3DES");
+ return NULL;
+ case 112:
+ return EVP_des_ede_cbc();
+ case 168:
+ return EVP_des_ede3_cbc();
+ default:
+ break;
+ };
+
+ ERROR_MSG("Invalid DES bit len %i", currentKey->getBitLen());
+
+ return NULL;
+}
+
+size_t OSSLCMACDES::getMacSize() const
+{
+ return 8;
+}
+
+const EVP_CIPHER* OSSLCMACAES::getEVPCipher() const
+{
+ switch(currentKey->getBitLen())
+ {
+ case 128:
+ return EVP_aes_128_cbc();
+ case 192:
+ return EVP_aes_192_cbc();
+ case 256:
+ return EVP_aes_256_cbc();
+ default:
+ break;
+ };
+
+ ERROR_MSG("Invalid AES bit len %i", currentKey->getBitLen());
+
+ return NULL;
+}
+
+size_t OSSLCMACAES::getMacSize() const
+{
+ return 16;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLCMAC.h b/SoftHSMv2/src/lib/crypto/OSSLCMAC.h
new file mode 100644
index 0000000..8d15e7c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLCMAC.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLCMAC.h
+
+ OpenSSL CMAC implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLCMAC_H
+#define _SOFTHSM_V2_OSSLCMAC_H
+
+#include "config.h"
+#include "OSSLEVPCMacAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLCMACDES : public OSSLEVPCMacAlgorithm
+{
+protected:
+ virtual const EVP_CIPHER* getEVPCipher() const;
+ virtual size_t getMacSize() const;
+};
+
+class OSSLCMACAES : public OSSLEVPCMacAlgorithm
+{
+protected:
+ virtual const EVP_CIPHER* getEVPCipher() const;
+ virtual size_t getMacSize() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLHMAC_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLComp.cpp b/SoftHSMv2/src/lib/crypto/OSSLComp.cpp
new file mode 100644
index 0000000..ede710b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLComp.cpp
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2016 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLUtil.cpp
+
+ Adding OpenSSL forward-compatible code as suggested by OpenSSL
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLComp.h"
+#include <openssl/opensslv.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#ifdef WITH_ECC
+#include <openssl/ecdsa.h>
+#endif
+#include <openssl/rsa.h>
+
+#include <string.h>
+
+// EVP digest routines
+EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+ EVP_MD_CTX *ctx = (EVP_MD_CTX*)OPENSSL_malloc(sizeof *ctx);
+
+ if (ctx)
+ EVP_MD_CTX_init(ctx);
+
+ return ctx;
+}
+
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+ if (ctx)
+ {
+ EVP_MD_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+ }
+}
+
+// HMAC routines
+HMAC_CTX *HMAC_CTX_new(void)
+{
+ HMAC_CTX *ctx = (HMAC_CTX*)OPENSSL_malloc(sizeof(*ctx));
+ if (ctx == NULL) return NULL;
+
+ HMAC_CTX_init(ctx);
+
+ return ctx;
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+ if (ctx == NULL) return;
+
+ HMAC_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+
+// DH routines
+void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = dh->p;
+ if (q != NULL)
+ *q = dh->q;
+ if (g != NULL)
+ *g = dh->g;
+}
+
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL. q may remain NULL.
+ */
+ if ((dh->p == NULL && p == NULL)
+ || (dh->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL)
+ {
+ BN_free(dh->p);
+ dh->p = p;
+ }
+ if (q != NULL)
+ {
+ BN_free(dh->q);
+ dh->q = q;
+ }
+ if (g != NULL)
+ {
+ BN_free(dh->g);
+ dh->g = g;
+ }
+
+ if (q != NULL)
+ {
+ dh->length = BN_num_bits(q);
+ }
+
+ return 1;
+}
+
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = dh->pub_key;
+ if (priv_key != NULL)
+ *priv_key = dh->priv_key;
+}
+
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in dh is NULL, the corresponding input
+ * parameters MUST be non-NULL. The priv_key field may
+ * be left NULL.
+ */
+ if (dh->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL)
+ {
+ BN_free(dh->pub_key);
+ dh->pub_key = pub_key;
+ }
+ if (priv_key != NULL)
+ {
+ BN_free(dh->priv_key);
+ dh->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+long DH_get_length(const DH *dh)
+{
+ return dh->length;
+}
+
+int DH_set_length(DH *dh, long length)
+{
+ dh->length = length;
+
+ return 1;
+}
+
+// DSA routines
+void DSA_get0_pqg(const DSA *d,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+ if (p != NULL)
+ *p = d->p;
+ if (q != NULL)
+ *q = d->q;
+ if (g != NULL)
+ *g = d->g;
+}
+
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+ /* If the fields p, q and g in d are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((d->p == NULL && p == NULL)
+ || (d->q == NULL && q == NULL)
+ || (d->g == NULL && g == NULL))
+ return 0;
+
+ if (p != NULL)
+ {
+ BN_free(d->p);
+ d->p = p;
+ }
+ if (q != NULL)
+ {
+ BN_free(d->q);
+ d->q = q;
+ }
+ if (g != NULL)
+ {
+ BN_free(d->g);
+ d->g = g;
+ }
+
+ return 1;
+}
+
+void DSA_get0_key(const DSA *d,
+ const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+ if (pub_key != NULL)
+ *pub_key = d->pub_key;
+ if (priv_key != NULL)
+ *priv_key = d->priv_key;
+}
+
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+ /* If the field pub_key in d is NULL, the corresponding input
+ * parameters MUST be non-NULL. The priv_key field may
+ * be left NULL.
+ */
+ if (d->pub_key == NULL && pub_key == NULL)
+ return 0;
+
+ if (pub_key != NULL)
+ {
+ BN_free(d->pub_key);
+ d->pub_key = pub_key;
+ }
+ if (priv_key != NULL)
+ {
+ BN_free(d->priv_key);
+ d->priv_key = priv_key;
+ }
+
+ return 1;
+}
+
+// DSA_SIG routines
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+ return 1;
+}
+
+// ECDSA_SIG routines
+#ifdef WITH_ECC
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+ if (pr != NULL)
+ *pr = sig->r;
+ if (ps != NULL)
+ *ps = sig->s;
+}
+
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+ if (r == NULL || s == NULL)
+ return 0;
+ BN_clear_free(sig->r);
+ BN_clear_free(sig->s);
+ sig->r = r;
+ sig->s = s;
+
+ return 1;
+}
+#endif
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+ /* If the fields n and e in r are NULL, the corresponding input
+ * parameters MUST be non-NULL for n and e. d may be
+ * left NULL (in case only the public key is used).
+ */
+ if ((r->n == NULL && n == NULL)
+ || (r->e == NULL && e == NULL))
+ return 0;
+
+ if (n != NULL)
+ {
+ BN_free(r->n);
+ r->n = n;
+ }
+ if (e != NULL)
+ {
+ BN_free(r->e);
+ r->e = e;
+ }
+ if (d != NULL)
+ {
+ BN_free(r->d);
+ r->d = d;
+ }
+
+ return 1;
+}
+
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+ /* If the fields p and q in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->p == NULL && p == NULL)
+ || (r->q == NULL && q == NULL))
+ return 0;
+
+ if (p != NULL)
+ {
+ BN_free(r->p);
+ r->p = p;
+ }
+ if (q != NULL)
+ {
+ BN_free(r->q);
+ r->q = q;
+ }
+
+ return 1;
+}
+
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->dmp1 == NULL && dmp1 == NULL)
+ || (r->dmq1 == NULL && dmq1 == NULL)
+ || (r->iqmp == NULL && iqmp == NULL))
+ return 0;
+
+ if (dmp1 != NULL)
+ {
+ BN_free(r->dmp1);
+ r->dmp1 = dmp1;
+ }
+ if (dmq1 != NULL)
+ {
+ BN_free(r->dmq1);
+ r->dmq1 = dmq1;
+ }
+ if (iqmp != NULL)
+ {
+ BN_free(r->iqmp);
+ r->iqmp = iqmp;
+ }
+
+ return 1;
+}
+
+void RSA_get0_key(const RSA *r,
+ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+ if (n != NULL)
+ *n = r->n;
+ if (e != NULL)
+ *e = r->e;
+ if (d != NULL)
+ *d = r->d;
+}
+
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+ if (p != NULL)
+ *p = r->p;
+ if (q != NULL)
+ *q = r->q;
+}
+
+void RSA_get0_crt_params(const RSA *r,
+ const BIGNUM **dmp1, const BIGNUM **dmq1,
+ const BIGNUM **iqmp)
+{
+ if (dmp1 != NULL)
+ *dmp1 = r->dmp1;
+ if (dmq1 != NULL)
+ *dmq1 = r->dmq1;
+ if (iqmp != NULL)
+ *iqmp = r->iqmp;
+}
+
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLComp.h b/SoftHSMv2/src/lib/crypto/OSSLComp.h
new file mode 100644
index 0000000..4bced32
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLComp.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLComp.h
+
+ Adding OpenSSL forward-compatible code as suggested by OpenSSL
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLCOMP_H
+#define _SOFTHSM_V2_OSSLCOMP_H
+
+#include "config.h"
+#include <openssl/opensslv.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#ifdef WITH_ECC
+#include <openssl/ecdsa.h>
+#endif
+#include <openssl/rsa.h>
+
+// EVP digest routines
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+
+// HMAC routines
+HMAC_CTX *HMAC_CTX_new(void);
+void HMAC_CTX_free(HMAC_CTX *ctx);
+
+// DH routines
+void DH_get0_pqg(const DH *dh,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
+long DH_get_length(const DH *dh);
+int DH_set_length(DH *dh, long length);
+
+// DSA routines
+void DSA_get0_pqg(const DSA *d,
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DSA_get0_key(const DSA *d,
+ const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+
+// DSA_SIG routines
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+// ECDSA_SIG routines
+#ifdef WITH_ECC
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+#endif
+
+// RSA routines
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
+void RSA_get0_key(const RSA *r,
+ const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
+void RSA_get0_crt_params(const RSA *r,
+ const BIGNUM **dmp1, const BIGNUM **dmq1,
+ const BIGNUM **iqmp);
+
+#endif
+
+#endif // !_SOFTHSM_V2_OSSLCOMP_H
diff --git a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp
new file mode 100644
index 0000000..ad27482
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.cpp
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLCryptoFactory.cpp
+
+ This is an OpenSSL based cryptographic algorithm factory
+ *****************************************************************************/
+
+#include "config.h"
+#include "MutexFactory.h"
+#include "OSSLCryptoFactory.h"
+#include "OSSLRNG.h"
+#include "OSSLAES.h"
+#include "OSSLDES.h"
+#include "OSSLMD5.h"
+#include "OSSLSHA1.h"
+#include "OSSLSHA224.h"
+#include "OSSLSHA256.h"
+#include "OSSLSHA384.h"
+#include "OSSLSHA512.h"
+#include "OSSLCMAC.h"
+#include "OSSLHMAC.h"
+#include "OSSLRSA.h"
+#include "OSSLDSA.h"
+#include "OSSLDH.h"
+#ifdef WITH_ECC
+#include "OSSLECDH.h"
+#include "OSSLECDSA.h"
+#endif
+#ifdef WITH_GOST
+#include "OSSLGOSTR3411.h"
+#include "OSSLGOST.h"
+#endif
+
+#include <algorithm>
+#include <string.h>
+#include <openssl/opensslv.h>
+#include <openssl/ssl.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifdef WITH_GOST
+#include <openssl/objects.h>
+#endif
+
+#ifdef WITH_FIPS
+// Initialise the FIPS 140-2 selftest status
+bool OSSLCryptoFactory::FipsSelfTestStatus = false;
+#endif
+
+static unsigned nlocks;
+static Mutex** locks;
+
+// Mutex callback
+void lock_callback(int mode, int n, const char* file, int line)
+{
+ if ((unsigned) n >= nlocks)
+ {
+ ERROR_MSG("out of range [0..%u[ lock %d at %s:%d",
+ nlocks, n, file, line);
+
+ return;
+ }
+
+ Mutex* mtx = locks[(unsigned) n];
+
+ if (mode & CRYPTO_LOCK)
+ {
+ mtx->lock();
+ }
+ else
+ {
+ mtx->unlock();
+ }
+}
+
+// Constructor
+OSSLCryptoFactory::OSSLCryptoFactory()
+{
+ // Multi-thread support
+ nlocks = CRYPTO_num_locks();
+ locks = new Mutex*[nlocks];
+ for (unsigned i = 0; i < nlocks; i++)
+ {
+ locks[i] = MutexFactory::i()->getMutex();
+ }
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ setLockingCallback = false;
+ if (CRYPTO_get_locking_callback() == NULL)
+ {
+ CRYPTO_set_locking_callback(lock_callback);
+ setLockingCallback = true;
+ }
+#endif
+
+#ifdef WITH_FIPS
+ // Already in FIPS mode on reenter (avoiding selftests)
+ if (!FIPS_mode())
+ {
+ FipsSelfTestStatus = false;
+ if (!FIPS_mode_set(1))
+ {
+ ERROR_MSG("can't enter into FIPS mode");
+ return;
+ }
+ } else {
+ // Undo RAND_cleanup()
+ RAND_init_fips();
+ }
+ FipsSelfTestStatus = true;
+#endif
+
+ // Initialise OpenSSL
+ OpenSSL_add_all_algorithms();
+
+ // Initialise the one-and-only RNG
+ rng = new OSSLRNG();
+
+#ifdef WITH_GOST
+ // Load engines
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ ENGINE_load_builtin_engines();
+#else
+ OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN |
+ OPENSSL_INIT_LOAD_CONFIG, NULL);
+#endif
+
+ // Initialise the GOST engine
+ eg = ENGINE_by_id("gost");
+ if (eg == NULL)
+ {
+ ERROR_MSG("can't get the GOST engine");
+ return;
+ }
+ if (ENGINE_init(eg) <= 0)
+ {
+ ENGINE_free(eg);
+ eg = NULL;
+ ERROR_MSG("can't initialize the GOST engine");
+ return;
+ }
+ // better than digest_gost
+ EVP_GOST_34_11 = ENGINE_get_digest(eg, NID_id_GostR3411_94);
+ if (EVP_GOST_34_11 == NULL)
+ {
+ ERROR_MSG("can't get the GOST digest");
+ goto err;
+ }
+ // from the openssl.cnf
+ if (ENGINE_register_pkey_asn1_meths(eg) <= 0)
+ {
+ ERROR_MSG("can't register ASN.1 for the GOST engine");
+ goto err;
+ }
+ if (ENGINE_ctrl_cmd_string(eg,
+ "CRYPT_PARAMS",
+ "id-Gost28147-89-CryptoPro-A-ParamSet",
+ 0) <= 0)
+ {
+ ERROR_MSG("can't set params of the GOST engine");
+ goto err;
+ }
+ return;
+
+err:
+ ENGINE_finish(eg);
+ ENGINE_free(eg);
+ eg = NULL;
+ return;
+#endif
+}
+
+// Destructor
+OSSLCryptoFactory::~OSSLCryptoFactory()
+{
+#ifdef WITH_GOST
+ // Finish the GOST engine
+ if (eg != NULL)
+ {
+ ENGINE_finish(eg);
+ ENGINE_free(eg);
+ eg = NULL;
+ }
+#endif
+
+ // Destroy the one-and-only RNG
+ delete rng;
+
+ // Recycle locks
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ if (setLockingCallback)
+ {
+ CRYPTO_set_locking_callback(NULL);
+ }
+#endif
+ for (unsigned i = 0; i < nlocks; i++)
+ {
+ MutexFactory::i()->recycleMutex(locks[i]);
+ }
+ delete[] locks;
+}
+
+// Return the one-and-only instance
+OSSLCryptoFactory* OSSLCryptoFactory::i()
+{
+ if (!instance.get())
+ {
+ instance.reset(new OSSLCryptoFactory());
+ }
+
+ return instance.get();
+}
+
+// This will destroy the one-and-only instance.
+void OSSLCryptoFactory::reset()
+{
+ instance.reset();
+}
+
+#ifdef WITH_FIPS
+bool OSSLCryptoFactory::getFipsSelfTestStatus() const
+{
+ return FipsSelfTestStatus;
+}
+#endif
+
+// Create a concrete instance of a symmetric algorithm
+SymmetricAlgorithm* OSSLCryptoFactory::getSymmetricAlgorithm(SymAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case SymAlgo::AES:
+ return new OSSLAES();
+ case SymAlgo::DES:
+ case SymAlgo::DES3:
+ return new OSSLDES();
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of an asymmetric algorithm
+AsymmetricAlgorithm* OSSLCryptoFactory::getAsymmetricAlgorithm(AsymAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case AsymAlgo::RSA:
+ return new OSSLRSA();
+ case AsymAlgo::DSA:
+ return new OSSLDSA();
+ case AsymAlgo::DH:
+ return new OSSLDH();
+#ifdef WITH_ECC
+ case AsymAlgo::ECDH:
+ return new OSSLECDH();
+ case AsymAlgo::ECDSA:
+ return new OSSLECDSA();
+#endif
+#ifdef WITH_GOST
+ case AsymAlgo::GOST:
+ return new OSSLGOST();
+#endif
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of a hash algorithm
+HashAlgorithm* OSSLCryptoFactory::getHashAlgorithm(HashAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case HashAlgo::MD5:
+ return new OSSLMD5();
+ case HashAlgo::SHA1:
+ return new OSSLSHA1();
+ case HashAlgo::SHA224:
+ return new OSSLSHA224();
+ case HashAlgo::SHA256:
+ return new OSSLSHA256();
+ case HashAlgo::SHA384:
+ return new OSSLSHA384();
+ case HashAlgo::SHA512:
+ return new OSSLSHA512();
+#ifdef WITH_GOST
+ case HashAlgo::GOST:
+ return new OSSLGOSTR3411();
+#endif
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Create a concrete instance of a MAC algorithm
+MacAlgorithm* OSSLCryptoFactory::getMacAlgorithm(MacAlgo::Type algorithm)
+{
+ switch (algorithm)
+ {
+ case MacAlgo::HMAC_MD5:
+ return new OSSLHMACMD5();
+ case MacAlgo::HMAC_SHA1:
+ return new OSSLHMACSHA1();
+ case MacAlgo::HMAC_SHA224:
+ return new OSSLHMACSHA224();
+ case MacAlgo::HMAC_SHA256:
+ return new OSSLHMACSHA256();
+ case MacAlgo::HMAC_SHA384:
+ return new OSSLHMACSHA384();
+ case MacAlgo::HMAC_SHA512:
+ return new OSSLHMACSHA512();
+#ifdef WITH_GOST
+ case MacAlgo::HMAC_GOST:
+ return new OSSLHMACGOSTR3411();
+#endif
+ case MacAlgo::CMAC_DES:
+ return new OSSLCMACDES();
+ case MacAlgo::CMAC_AES:
+ return new OSSLCMACAES();
+ default:
+ // No algorithm implementation is available
+ ERROR_MSG("Unknown algorithm '%i'", algorithm);
+
+ return NULL;
+ }
+
+ // No algorithm implementation is available
+ return NULL;
+}
+
+// Get the global RNG (may be an unique RNG per thread)
+RNG* OSSLCryptoFactory::getRNG(RNGImpl::Type name /* = RNGImpl::Default */)
+{
+ if (name == RNGImpl::Default)
+ {
+ return rng;
+ }
+ else
+ {
+ // No RNG implementation is available
+ ERROR_MSG("Unknown RNG '%i'", name);
+
+ return NULL;
+ }
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h
new file mode 100644
index 0000000..e8bfa2c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLCryptoFactory.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLCryptoFactory.h
+
+ This is an OpenSSL based cryptographic algorithm factory
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLCRYPTOFACTORY_H
+#define _SOFTHSM_V2_OSSLCRYPTOFACTORY_H
+
+#include "config.h"
+#include "CryptoFactory.h"
+#include "SymmetricAlgorithm.h"
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+#include <memory>
+#ifdef WITH_GOST
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#endif
+
+class OSSLCryptoFactory : public CryptoFactory
+{
+public:
+ // Return the one-and-only instance
+ static OSSLCryptoFactory* i();
+
+ // This will destroy the one-and-only instance.
+ static void reset();
+
+#ifdef WITH_FIPS
+ // Return the FIPS 140-2 selftest status
+ virtual bool getFipsSelfTestStatus() const;
+#endif
+
+ // Create a concrete instance of a symmetric algorithm
+ virtual SymmetricAlgorithm* getSymmetricAlgorithm(SymAlgo::Type algorithm);
+
+ // Create a concrete instance of an asymmetric algorithm
+ virtual AsymmetricAlgorithm* getAsymmetricAlgorithm(AsymAlgo::Type algorithm);
+
+ // Create a concrete instance of a hash algorithm
+ virtual HashAlgorithm* getHashAlgorithm(HashAlgo::Type algorithm);
+
+ // Create a concrete instance of a MAC algorithm
+ virtual MacAlgorithm* getMacAlgorithm(MacAlgo::Type algorithm);
+
+ // Get the global RNG (may be an unique RNG per thread)
+ virtual RNG* getRNG(RNGImpl::Type name = RNGImpl::Default);
+
+ // Destructor
+ virtual ~OSSLCryptoFactory();
+
+#ifdef WITH_GOST
+ // The EVP_MD for GOST R 34.11-94
+ const EVP_MD *EVP_GOST_34_11;
+#endif
+
+private:
+ // Constructor
+ OSSLCryptoFactory();
+
+ // The one-and-only instance
+#ifdef HAVE_CXX11
+ static std::unique_ptr<OSSLCryptoFactory> instance;
+#else
+ static std::auto_ptr<OSSLCryptoFactory> instance;
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ bool setLockingCallback;
+#endif
+
+#ifdef WITH_FIPS
+ // The FIPS 140-2 selftest status
+ static bool FipsSelfTestStatus;
+#endif
+
+ // The one-and-only RNG instance
+ RNG* rng;
+
+#ifdef WITH_GOST
+ // The GOST engine
+ ENGINE *eg;
+#endif
+};
+
+#endif // !_SOFTHSM_V2_OSSLCRYPTOFACTORY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDES.cpp b/SoftHSMv2/src/lib/crypto/OSSLDES.cpp
new file mode 100644
index 0000000..4fb56b5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDES.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDES.cpp
+
+ OpenSSL (3)DES implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLDES.h"
+#include <algorithm>
+#include "odd.h"
+
+bool OSSLDES::wrapKey(const SymmetricKey* /*key*/, const SymWrap::Type /*mode*/, const ByteString& /*in*/, ByteString& /*out*/)
+{
+ ERROR_MSG("DES does not support key wrapping");
+
+ return false;
+}
+
+bool OSSLDES::unwrapKey(const SymmetricKey* /*key*/, const SymWrap::Type /*mode*/, const ByteString& /*in*/, ByteString& /*out*/)
+{
+ ERROR_MSG("DES does not support key unwrapping");
+
+ return false;
+}
+
+const EVP_CIPHER* OSSLDES::getCipher() const
+{
+ if (currentKey == NULL) return NULL;
+
+ // Check currentKey bit length; 3DES only supports 56-bit, 112-bit or 168-bit keys
+ if (
+#ifndef WITH_FIPS
+ (currentKey->getBitLen() != 56) &&
+#endif
+ (currentKey->getBitLen() != 112) &&
+ (currentKey->getBitLen() != 168))
+ {
+ ERROR_MSG("Invalid DES currentKey length (%d bits)", currentKey->getBitLen());
+
+ return NULL;
+ }
+
+ // People shouldn't really be using 56-bit DES keys, generate a warning
+ if (currentKey->getBitLen() == 56)
+ {
+ DEBUG_MSG("CAUTION: use of 56-bit DES keys is not recommended!");
+ }
+
+ // Determine the cipher mode
+ if (currentCipherMode == SymMode::CBC)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 56:
+ return EVP_des_cbc();
+ case 112:
+ return EVP_des_ede_cbc();
+ case 168:
+ return EVP_des_ede3_cbc();
+ };
+ }
+ else if (currentCipherMode == SymMode::ECB)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 56:
+ return EVP_des_ecb();
+ case 112:
+ return EVP_des_ede_ecb();
+ case 168:
+ return EVP_des_ede3_ecb();
+ };
+ }
+ else if (currentCipherMode == SymMode::OFB)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 56:
+ return EVP_des_ofb();
+ case 112:
+ return EVP_des_ede_ofb();
+ case 168:
+ return EVP_des_ede3_ofb();
+ };
+ }
+ else if (currentCipherMode == SymMode::CFB)
+ {
+ switch(currentKey->getBitLen())
+ {
+ case 56:
+ return EVP_des_cfb();
+ case 112:
+ return EVP_des_ede_cfb();
+ case 168:
+ return EVP_des_ede3_cfb();
+ };
+ }
+
+ ERROR_MSG("Invalid DES cipher mode %i", currentCipherMode);
+
+ return NULL;
+}
+
+bool OSSLDES::generateKey(SymmetricKey& key, RNG* rng /* = NULL */)
+{
+ if (rng == NULL)
+ {
+ return false;
+ }
+
+ if (key.getBitLen() == 0)
+ {
+ return false;
+ }
+
+ ByteString keyBits;
+
+ // don't count parity bit
+ if (!rng->generateRandom(keyBits, key.getBitLen()/7))
+ {
+ return false;
+ }
+
+ // fix the odd parity
+ size_t i;
+ for (i = 0; i < keyBits.size(); i++)
+ {
+ keyBits[i] = odd_parity[keyBits[i]];
+ }
+
+ return key.setKeyBits(keyBits);
+}
+
+size_t OSSLDES::getBlockSize() const
+{
+ // The block size is 64 bits
+ return 64 >> 3;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDES.h b/SoftHSMv2/src/lib/crypto/OSSLDES.h
new file mode 100644
index 0000000..1ecdc8c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDES.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDES.h
+
+ OpenSSL AES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDES_H
+#define _SOFTHSM_V2_OSSLDES_H
+
+#include <openssl/evp.h>
+#include <string>
+#include "config.h"
+#include "OSSLEVPSymmetricAlgorithm.h"
+
+class OSSLDES : public OSSLEVPSymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~OSSLDES() { }
+
+ // Wrap/Unwrap keys
+ virtual bool wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ virtual bool unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out);
+
+ // Generate key
+ virtual bool generateKey(SymmetricKey& key, RNG* rng = NULL);
+
+ // Return the block size
+ virtual size_t getBlockSize() const;
+
+protected:
+ // Return the right EVP cipher for the operation
+ virtual const EVP_CIPHER* getCipher() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLDES_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDH.cpp b/SoftHSMv2/src/lib/crypto/OSSLDH.cpp
new file mode 100644
index 0000000..ee61733
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDH.cpp
@@ -0,0 +1,430 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDH.cpp
+
+ OpenSSL Diffie-Hellman asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLDH.h"
+#include "CryptoFactory.h"
+#include "DHParameters.h"
+#include "OSSLComp.h"
+#include "OSSLDHKeyPair.h"
+#include "OSSLUtil.h"
+#include <algorithm>
+#include <openssl/dh.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+// Signing functions
+bool OSSLDH::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("DH does not support signing");
+
+ return false;
+}
+
+bool OSSLDH::signUpdate(const ByteString& /*dataToSign*/)
+{
+ ERROR_MSG("DH does not support signing");
+
+ return false;
+}
+
+bool OSSLDH::signFinal(ByteString& /*signature*/)
+{
+ ERROR_MSG("DH does not support signing");
+
+ return false;
+}
+
+// Verification functions
+bool OSSLDH::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("DH does not support verifying");
+
+ return false;
+}
+
+bool OSSLDH::verifyUpdate(const ByteString& /*originalData*/)
+{
+ ERROR_MSG("DH does not support verifying");
+
+ return false;
+}
+
+bool OSSLDH::verifyFinal(const ByteString& /*signature*/)
+{
+ ERROR_MSG("DH does not support verifying");
+
+ return false;
+}
+
+// Encryption functions
+bool OSSLDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DH does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool OSSLDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DH does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool OSSLDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(DHParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for DH key generation");
+
+ return false;
+ }
+
+ DHParameters* params = (DHParameters*) parameters;
+
+ // Generate the key-pair
+ DH* dh = DH_new();
+ if (dh == NULL)
+ {
+ ERROR_MSG("Failed to instantiate OpenSSL DH object");
+
+ return false;
+ }
+
+ BIGNUM* bn_p = OSSL::byteString2bn(params->getP());
+ BIGNUM* bn_g = OSSL::byteString2bn(params->getG());
+
+ if (!DH_set0_pqg(dh, bn_p, NULL, bn_g))
+ {
+ ERROR_MSG("DH set pqg failed (0x%08X)", ERR_get_error());
+
+ BN_free(bn_p);
+ BN_free(bn_g);
+ DH_free(dh);
+
+ return false;
+ }
+
+ if (params->getXBitLength() > 0)
+ {
+ if (!DH_set_length(dh, params->getXBitLength()))
+ {
+ ERROR_MSG("DH set length failed (0x%08X)", ERR_get_error());
+
+ DH_free(dh);
+
+ return false;
+ }
+ }
+
+ if (DH_generate_key(dh) != 1)
+ {
+ ERROR_MSG("DH key generation failed (0x%08X)", ERR_get_error());
+
+ DH_free(dh);
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ OSSLDHKeyPair* kp = new OSSLDHKeyPair();
+
+ ((OSSLDHPublicKey*) kp->getPublicKey())->setFromOSSL(dh);
+ ((OSSLDHPrivateKey*) kp->getPrivateKey())->setFromOSSL(dh);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ DH_free(dh);
+
+ return true;
+}
+
+bool OSSLDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
+{
+ // Check parameters
+ if ((ppSymmetricKey == NULL) ||
+ (publicKey == NULL) ||
+ (privateKey == NULL))
+ {
+ return false;
+ }
+
+ // Get keys
+ DH *pub = ((OSSLDHPublicKey *)publicKey)->getOSSLKey();
+ DH *priv = ((OSSLDHPrivateKey *)privateKey)->getOSSLKey();
+ if (pub == NULL || priv == NULL)
+ {
+ ERROR_MSG("Failed to get OpenSSL DH keys");
+
+ return false;
+ }
+ const BIGNUM* bn_pub_key = NULL;
+ DH_get0_key(pub, &bn_pub_key, NULL);
+ if (bn_pub_key == NULL)
+ {
+ ERROR_MSG("Failed to get OpenSSL DH keys");
+
+ return false;
+ }
+
+ // Derive the secret
+ ByteString secret, derivedSecret;
+ int size = DH_size(priv);
+ secret.wipe(size);
+ derivedSecret.wipe(size);
+ int keySize = DH_compute_key(&derivedSecret[0], bn_pub_key, priv);
+
+ if (keySize <= 0)
+ {
+ ERROR_MSG("DH key derivation failed (0x%08X)", ERR_get_error());
+
+ return false;
+ }
+
+ // We compensate that OpenSSL removes leading zeros
+ memcpy(&secret[0] + size - keySize, &derivedSecret[0], keySize);
+
+ *ppSymmetricKey = new SymmetricKey(secret.size() * 8);
+ if (*ppSymmetricKey == NULL)
+ return false;
+ if (!(*ppSymmetricKey)->setKeyBits(secret))
+ {
+ delete *ppSymmetricKey;
+ *ppSymmetricKey = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+unsigned long OSSLDH::getMinKeySize()
+{
+#ifdef WITH_FIPS
+ // OPENSSL_DH_FIPS_MIN_MODULUS_BITS is 1024
+ return 1024;
+#else
+ return 512;
+#endif
+}
+
+unsigned long OSSLDH::getMaxKeySize()
+{
+ return OPENSSL_DH_MAX_MODULUS_BITS;
+}
+
+bool OSSLDH::generateParameters(AsymmetricParameters** ppParams, void* parameters /* = NULL */, RNG* /*rng = NULL*/)
+{
+ if ((ppParams == NULL) || (parameters == NULL))
+ {
+ return false;
+ }
+
+ size_t bitLen = (size_t) parameters;
+
+ if (bitLen < getMinKeySize() || bitLen > getMaxKeySize())
+ {
+ ERROR_MSG("This DH key size is not supported");
+
+ return false;
+ }
+
+ DH* dh = DH_new();
+ if (dh == NULL)
+ {
+ ERROR_MSG("Failed to create DH object");
+
+ return false;
+ }
+
+ if (!DH_generate_parameters_ex(dh, bitLen, 2, NULL))
+ {
+ ERROR_MSG("Failed to generate %d bit DH parameters", bitLen);
+
+ DH_free(dh);
+
+ return false;
+ }
+
+ // Store the DH parameters
+ DHParameters* params = new DHParameters();
+
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_g = NULL;
+
+ DH_get0_pqg(dh, &bn_p, NULL, &bn_g);
+ ByteString p = OSSL::bn2ByteString(bn_p); params->setP(p);
+ ByteString g = OSSL::bn2ByteString(bn_g); params->setG(g);
+
+ *ppParams = params;
+
+ DH_free(dh);
+
+ return true;
+}
+
+bool OSSLDH::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ OSSLDHKeyPair* kp = new OSSLDHKeyPair();
+
+ bool rv = true;
+
+ if (!((DHPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((DHPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool OSSLDH::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLDHPublicKey* pub = new OSSLDHPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool OSSLDH::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLDHPrivateKey* priv = new OSSLDHPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* OSSLDH::newPublicKey()
+{
+ return (PublicKey*) new OSSLDHPublicKey();
+}
+
+PrivateKey* OSSLDH::newPrivateKey()
+{
+ return (PrivateKey*) new OSSLDHPrivateKey();
+}
+
+AsymmetricParameters* OSSLDH::newParameters()
+{
+ return (AsymmetricParameters*) new DHParameters();
+}
+
+bool OSSLDH::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ DHParameters* params = new DHParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDH.h b/SoftHSMv2/src/lib/crypto/OSSLDH.h
new file mode 100644
index 0000000..d611aee
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDH.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDH.h
+
+ OpenSSL Diffie-Hellman asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDH_H
+#define _SOFTHSM_V2_OSSLDH_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <openssl/dh.h>
+
+class OSSLDH : public AsymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~OSSLDH() { }
+
+ // Signing functions
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool generateParameters(AsymmetricParameters** ppParams, void* parameters = NULL, RNG* rng = NULL);
+ virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_OSSLDH_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.cpp b/SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.cpp
new file mode 100644
index 0000000..4865553
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDHKeyPair.cpp
+
+ OpenSSL Diffie-Hellman key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLDHKeyPair.h"
+
+// Set the public key
+void OSSLDHKeyPair::setPublicKey(OSSLDHPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void OSSLDHKeyPair::setPrivateKey(OSSLDHPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* OSSLDHKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* OSSLDHKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* OSSLDHKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* OSSLDHKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.h b/SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.h
new file mode 100644
index 0000000..320d5ab
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDHKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDHKeyPair.h
+
+ OpenSSL Diffie-Hellman key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDHKEYPAIR_H
+#define _SOFTHSM_V2_OSSLDHKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "OSSLDHPublicKey.h"
+#include "OSSLDHPrivateKey.h"
+
+class OSSLDHKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(OSSLDHPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(OSSLDHPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ OSSLDHPublicKey pubKey;
+
+ // The private key
+ OSSLDHPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLDHKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.cpp
new file mode 100644
index 0000000..5571a88
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDHPrivateKey.cpp
+
+ OpenSSL Diffie-Hellman private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLComp.h"
+#include "OSSLDHPrivateKey.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+#include <string.h>
+
+// Constructors
+OSSLDHPrivateKey::OSSLDHPrivateKey()
+{
+ dh = NULL;
+}
+
+OSSLDHPrivateKey::OSSLDHPrivateKey(const DH* inDH)
+{
+ dh = NULL;
+
+ setFromOSSL(inDH);
+}
+
+// Destructor
+OSSLDHPrivateKey::~OSSLDHPrivateKey()
+{
+ DH_free(dh);
+}
+
+// The type
+/*static*/ const char* OSSLDHPrivateKey::type = "OpenSSL DH Private Key";
+
+// Set from OpenSSL representation
+void OSSLDHPrivateKey::setFromOSSL(const DH* inDH)
+{
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_g = NULL;
+ const BIGNUM* bn_priv_key = NULL;
+
+ DH_get0_pqg(inDH, &bn_p, NULL, &bn_g);
+ DH_get0_key(inDH, NULL, &bn_priv_key);
+
+ if (bn_p)
+ {
+ ByteString inP = OSSL::bn2ByteString(bn_p);
+ setP(inP);
+ }
+ if (bn_g)
+ {
+ ByteString inG = OSSL::bn2ByteString(bn_g);
+ setG(inG);
+ }
+ if (bn_priv_key)
+ {
+ ByteString inX = OSSL::bn2ByteString(bn_priv_key);
+ setX(inX);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLDHPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DH private key components
+void OSSLDHPrivateKey::setX(const ByteString& inX)
+{
+ DHPrivateKey::setX(inX);
+
+ if (dh)
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+}
+
+
+// Setters for the DH public key components
+void OSSLDHPrivateKey::setP(const ByteString& inP)
+{
+ DHPrivateKey::setP(inP);
+
+ if (dh)
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+}
+
+void OSSLDHPrivateKey::setG(const ByteString& inG)
+{
+ DHPrivateKey::setG(inG);
+
+ if (dh)
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString OSSLDHPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ if (dh == NULL) createOSSLKey();
+ if (dh == NULL) return der;
+ EVP_PKEY* pkey = EVP_PKEY_new();
+ if (pkey == NULL) return der;
+ if (!EVP_PKEY_set1_DH(pkey, dh))
+ {
+ EVP_PKEY_free(pkey);
+ return der;
+ }
+ PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey);
+ EVP_PKEY_free(pkey);
+ if (p8inf == NULL) return der;
+ int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL);
+ if (len < 0)
+ {
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return der;
+ }
+ der.resize(len);
+ unsigned char* priv = &der[0];
+ int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (len2 != len) der.wipe();
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool OSSLDHPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ int len = ber.size();
+ if (len <= 0) return false;
+ const unsigned char* priv = ber.const_byte_str();
+ PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &priv, len);
+ if (p8 == NULL) return false;
+ EVP_PKEY* pkey = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (pkey == NULL) return false;
+ DH* key = EVP_PKEY_get1_DH(pkey);
+ EVP_PKEY_free(pkey);
+ if (key == NULL) return false;
+ setFromOSSL(key);
+ DH_free(key);
+ return true;
+}
+
+// Retrieve the OpenSSL representation of the key
+DH* OSSLDHPrivateKey::getOSSLKey()
+{
+ if (dh == NULL) createOSSLKey();
+
+ return dh;
+}
+
+// Create the OpenSSL representation of the key
+void OSSLDHPrivateKey::createOSSLKey()
+{
+ if (dh != NULL) return;
+
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ ERROR_MSG("Could not create BN_CTX");
+ return;
+ }
+
+ dh = DH_new();
+ if (dh == NULL)
+ {
+ ERROR_MSG("Could not create DH object");
+ return;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ DH_set_method(dh, FIPS_dh_openssl());
+ else
+ DH_set_method(dh, DH_OpenSSL());
+#else
+ DH_set_method(dh, DH_OpenSSL());
+#endif
+
+#else
+ DH_set_method(dh, DH_OpenSSL());
+#endif
+
+ BIGNUM* bn_p = OSSL::byteString2bn(p);
+ BIGNUM* bn_g = OSSL::byteString2bn(g);
+ BIGNUM* bn_priv_key = OSSL::byteString2bn(x);
+ BIGNUM* bn_pub_key = BN_new();
+
+ BN_mod_exp(bn_pub_key, bn_g, bn_priv_key, bn_p, ctx);
+ BN_CTX_free(ctx);
+
+ DH_set0_pqg(dh, bn_p, NULL, bn_g);
+ DH_set0_key(dh, bn_pub_key, bn_priv_key);
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.h b/SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.h
new file mode 100644
index 0000000..2cf8599
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDHPrivateKey.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDHPrivateKey.h
+
+ OpenSSL Diffie-Hellman private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDHPRIVATEKEY_H
+#define _SOFTHSM_V2_OSSLDHPRIVATEKEY_H
+
+#include "config.h"
+#include "DHPrivateKey.h"
+#include <openssl/dh.h>
+
+class OSSLDHPrivateKey : public DHPrivateKey
+{
+public:
+ // Constructors
+ OSSLDHPrivateKey();
+
+ OSSLDHPrivateKey(const DH* inDH);
+
+ // Destructor
+ virtual ~OSSLDHPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DH private key components
+ virtual void setX(const ByteString& inX);
+
+ // Setters for the DH public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setG(const ByteString& inG);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const DH* inDH);
+
+ // Retrieve the OpenSSL representation of the key
+ DH* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ DH* dh;
+
+ // Create the OpenSSL representation of the key
+ void createOSSLKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLDHPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.cpp
new file mode 100644
index 0000000..e261726
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDHPublicKey.cpp
+
+ OpenSSL Diffie-Hellman public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLComp.h"
+#include "OSSLDHPublicKey.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+#include <string.h>
+
+// Constructors
+OSSLDHPublicKey::OSSLDHPublicKey()
+{
+ dh = NULL;
+}
+
+OSSLDHPublicKey::OSSLDHPublicKey(const DH* inDH)
+{
+ dh = NULL;
+
+ setFromOSSL(inDH);
+}
+
+// Destructor
+OSSLDHPublicKey::~OSSLDHPublicKey()
+{
+ DH_free(dh);
+}
+
+// The type
+/*static*/ const char* OSSLDHPublicKey::type = "OpenSSL DH Public Key";
+
+// Set from OpenSSL representation
+void OSSLDHPublicKey::setFromOSSL(const DH* inDH)
+{
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_g = NULL;
+ const BIGNUM* bn_pub_key = NULL;
+
+ DH_get0_pqg(inDH, &bn_p, NULL, &bn_g);
+ DH_get0_key(inDH, &bn_pub_key, NULL);
+
+ if (bn_p)
+ {
+ ByteString inP = OSSL::bn2ByteString(bn_p);
+ setP(inP);
+ }
+ if (bn_g)
+ {
+ ByteString inG = OSSL::bn2ByteString(bn_g);
+ setG(inG);
+ }
+ if (bn_pub_key)
+ {
+ ByteString inY = OSSL::bn2ByteString(bn_pub_key);
+ setY(inY);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLDHPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DH public key components
+void OSSLDHPublicKey::setP(const ByteString& inP)
+{
+ DHPublicKey::setP(inP);
+
+ if (dh)
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+}
+
+void OSSLDHPublicKey::setG(const ByteString& inG)
+{
+ DHPublicKey::setG(inG);
+
+ if (dh)
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+}
+
+void OSSLDHPublicKey::setY(const ByteString& inY)
+{
+ DHPublicKey::setY(inY);
+
+ if (dh)
+ {
+ DH_free(dh);
+ dh = NULL;
+ }
+}
+
+// Retrieve the OpenSSL representation of the key
+DH* OSSLDHPublicKey::getOSSLKey()
+{
+ if (dh == NULL) createOSSLKey();
+
+ return dh;
+}
+
+// Create the OpenSSL representation of the key
+void OSSLDHPublicKey::createOSSLKey()
+{
+ if (dh != NULL) return;
+
+ dh = DH_new();
+ if (dh == NULL)
+ {
+ ERROR_MSG("Could not create DH object");
+ return;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ DH_set_method(dh, FIPS_dh_openssl());
+ else
+ DH_set_method(dh, DH_OpenSSL());
+#else
+ DH_set_method(dh, DH_OpenSSL());
+#endif
+
+#else
+ DH_set_method(dh, DH_OpenSSL());
+#endif
+
+ BIGNUM* bn_p = OSSL::byteString2bn(p);
+ BIGNUM* bn_g = OSSL::byteString2bn(g);
+ BIGNUM* bn_pub_key = OSSL::byteString2bn(y);
+
+ DH_set0_pqg(dh, bn_p, NULL, bn_g);
+ DH_set0_key(dh, bn_pub_key, NULL);
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.h b/SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.h
new file mode 100644
index 0000000..9f5eed8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDHPublicKey.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDHPublicKey.h
+
+ OpenSSL Diffie-Hellman public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDHPUBLICKEY_H
+#define _SOFTHSM_V2_OSSLDHPUBLICKEY_H
+
+#include "config.h"
+#include "DHPublicKey.h"
+#include <openssl/dh.h>
+
+class OSSLDHPublicKey : public DHPublicKey
+{
+public:
+ // Constructors
+ OSSLDHPublicKey();
+
+ OSSLDHPublicKey(const DH* inDH);
+
+ // Destructor
+ virtual ~OSSLDHPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DH public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setG(const ByteString& inG);
+ virtual void setY(const ByteString& inY);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const DH* inDH);
+
+ // Retrieve the OpenSSL representation of the key
+ DH* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ DH* dh;
+
+ // Create the OpenSSL representation of the key
+ void createOSSLKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLDHPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSA.cpp b/SoftHSMv2/src/lib/crypto/OSSLDSA.cpp
new file mode 100644
index 0000000..06b5d50
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSA.cpp
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSA.cpp
+
+ OpenSSL DSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLDSA.h"
+#include "CryptoFactory.h"
+#include "DSAParameters.h"
+#include "OSSLDSAKeyPair.h"
+#include "OSSLComp.h"
+#include "OSSLUtil.h"
+#include <algorithm>
+#include <openssl/dsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+// Constructor
+OSSLDSA::OSSLDSA()
+{
+ pCurrentHash = NULL;
+}
+
+// Destructor
+OSSLDSA::~OSSLDSA()
+{
+ if (pCurrentHash != NULL)
+ {
+ delete pCurrentHash;
+ }
+}
+
+// Signing functions
+bool OSSLDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (mechanism == AsymMech::DSA)
+ {
+ // Separate implementation for DSA signing without hash computation
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLDSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ OSSLDSAPrivateKey* pk = (OSSLDSAPrivateKey*) privateKey;
+ DSA* dsa = pk->getOSSLKey();
+
+ // Perform the signature operation
+ unsigned int sigLen = pk->getOutputLength();
+ signature.resize(sigLen);
+ memset(&signature[0], 0, sigLen);
+ int dLen = dataToSign.size();
+ DSA_SIG* sig = DSA_do_sign(dataToSign.const_byte_str(), dLen, dsa);
+ if (sig == NULL)
+ return false;
+ // Store the 2 values with padding
+ const BIGNUM* bn_r = NULL;
+ const BIGNUM* bn_s = NULL;
+ DSA_SIG_get0(sig, &bn_r, &bn_s);
+ BN_bn2bin(bn_r, &signature[sigLen / 2 - BN_num_bytes(bn_r)]);
+ BN_bn2bin(bn_s, &signature[sigLen - BN_num_bytes(bn_s)]);
+ DSA_SIG_free(sig);
+ return true;
+ }
+ else
+ {
+ // Call default implementation
+ return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
+ }
+}
+
+bool OSSLDSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLDSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ HashAlgo::Type hash = HashAlgo::Unknown;
+
+ switch (mechanism)
+ {
+ case AsymMech::DSA_SHA1:
+ hash = HashAlgo::SHA1;
+ break;
+ case AsymMech::DSA_SHA224:
+ hash = HashAlgo::SHA224;
+ break;
+ case AsymMech::DSA_SHA256:
+ hash = HashAlgo::SHA256;
+ break;
+ case AsymMech::DSA_SHA384:
+ hash = HashAlgo::SHA384;
+ break;
+ case AsymMech::DSA_SHA512:
+ hash = HashAlgo::SHA512;
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ pCurrentHash = CryptoFactory::i()->getHashAlgorithm(hash);
+
+ if (pCurrentHash == NULL)
+ {
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ if (!pCurrentHash->hashInit())
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLDSA::signUpdate(const ByteString& dataToSign)
+{
+ if (!AsymmetricAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ if (!pCurrentHash->hashUpdate(dataToSign))
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLDSA::signFinal(ByteString& signature)
+{
+ // Save necessary state before calling super class signFinal
+ OSSLDSAPrivateKey* pk = (OSSLDSAPrivateKey*) currentPrivateKey;
+
+ if (!AsymmetricAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ ByteString hash;
+
+ bool bFirstResult = pCurrentHash->hashFinal(hash);
+
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ if (!bFirstResult)
+ {
+ return false;
+ }
+
+ DSA* dsa = pk->getOSSLKey();
+
+ // Perform the signature operation
+ unsigned int sigLen = pk->getOutputLength();
+ signature.resize(sigLen);
+ memset(&signature[0], 0, sigLen);
+ DSA_SIG* sig = DSA_do_sign(&hash[0], hash.size(), dsa);
+ if (sig == NULL)
+ return false;
+ // Store the 2 values with padding
+ const BIGNUM* bn_r = NULL;
+ const BIGNUM* bn_s = NULL;
+ DSA_SIG_get0(sig, &bn_r, &bn_s);
+ BN_bn2bin(bn_r, &signature[sigLen / 2 - BN_num_bytes(bn_r)]);
+ BN_bn2bin(bn_s, &signature[sigLen - BN_num_bytes(bn_s)]);
+ DSA_SIG_free(sig);
+ return true;
+}
+
+// Verification functions
+bool OSSLDSA::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (mechanism == AsymMech::DSA)
+ {
+ // Separate implementation for DSA verification without hash computation
+
+ // Check if the private key is the right type
+ if (!publicKey->isOfType(OSSLDSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Perform the verify operation
+ OSSLDSAPublicKey* pk = (OSSLDSAPublicKey*) publicKey;
+ unsigned int sigLen = pk->getOutputLength();
+ if (signature.size() != sigLen)
+ return false;
+ DSA_SIG* sig = DSA_SIG_new();
+ if (sig == NULL)
+ return false;
+ const unsigned char *s = signature.const_byte_str();
+ BIGNUM* bn_r = BN_bin2bn(s, sigLen / 2, NULL);
+ BIGNUM* bn_s = BN_bin2bn(s + sigLen / 2, sigLen / 2, NULL);
+ if (bn_r == NULL || bn_s == NULL ||
+ !DSA_SIG_set0(sig, bn_r, bn_s))
+ {
+ DSA_SIG_free(sig);
+ return false;
+ }
+ int dLen = originalData.size();
+ int ret = DSA_do_verify(originalData.const_byte_str(), dLen, sig, pk->getOSSLKey());
+ if (ret != 1)
+ {
+ if (ret < 0)
+ ERROR_MSG("DSA verify failed (0x%08X)", ERR_get_error());
+
+ DSA_SIG_free(sig);
+ return false;
+ }
+
+ DSA_SIG_free(sig);
+ return true;
+ }
+ else
+ {
+ // Call the generic function
+ return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
+ }
+}
+
+bool OSSLDSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!publicKey->isOfType(OSSLDSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ HashAlgo::Type hash = HashAlgo::Unknown;
+
+ switch (mechanism)
+ {
+ case AsymMech::DSA_SHA1:
+ hash = HashAlgo::SHA1;
+ break;
+ case AsymMech::DSA_SHA224:
+ hash = HashAlgo::SHA224;
+ break;
+ case AsymMech::DSA_SHA256:
+ hash = HashAlgo::SHA256;
+ break;
+ case AsymMech::DSA_SHA384:
+ hash = HashAlgo::SHA384;
+ break;
+ case AsymMech::DSA_SHA512:
+ hash = HashAlgo::SHA512;
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ pCurrentHash = CryptoFactory::i()->getHashAlgorithm(hash);
+
+
+ if (pCurrentHash == NULL)
+ {
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ if (!pCurrentHash->hashInit())
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLDSA::verifyUpdate(const ByteString& originalData)
+{
+ if (!AsymmetricAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ if (!pCurrentHash->hashUpdate(originalData))
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLDSA::verifyFinal(const ByteString& signature)
+{
+ // Save necessary state before calling super class verifyFinal
+ OSSLDSAPublicKey* pk = (OSSLDSAPublicKey*) currentPublicKey;
+
+ if (!AsymmetricAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ ByteString hash;
+
+ bool bFirstResult = pCurrentHash->hashFinal(hash);
+
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ if (!bFirstResult)
+ {
+ return false;
+ }
+
+ // Perform the verify operation
+ unsigned int sigLen = pk->getOutputLength();
+ if (signature.size() != sigLen)
+ return false;
+ DSA_SIG* sig = DSA_SIG_new();
+ if (sig == NULL)
+ return false;
+ const unsigned char *s = signature.const_byte_str();
+ BIGNUM* bn_r = BN_bin2bn(s, sigLen / 2, NULL);
+ BIGNUM* bn_s = BN_bin2bn(s + sigLen / 2, sigLen / 2, NULL);
+ if (bn_r == NULL || bn_s == NULL ||
+ !DSA_SIG_set0(sig, bn_r, bn_s))
+ {
+ DSA_SIG_free(sig);
+ return false;
+ }
+ int ret = DSA_do_verify(&hash[0], hash.size(), sig, pk->getOSSLKey());
+ if (ret != 1)
+ {
+ if (ret < 0)
+ ERROR_MSG("DSA verify failed (0x%08X)", ERR_get_error());
+
+ DSA_SIG_free(sig);
+ return false;
+ }
+
+ DSA_SIG_free(sig);
+ return true;
+}
+
+// Encryption functions
+bool OSSLDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DSA does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool OSSLDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("DSA does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool OSSLDSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(DSAParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for DSA key generation");
+
+ return false;
+ }
+
+ DSAParameters* params = (DSAParameters*) parameters;
+
+ // Generate the key-pair
+ DSA* dsa = DSA_new();
+ if (dsa == NULL)
+ {
+ ERROR_MSG("Failed to instantiate OpenSSL DSA object");
+
+ return false;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+ DSA_set_method(dsa, DSA_get_default_method());
+
+ BIGNUM* bn_p = OSSL::byteString2bn(params->getP());
+ BIGNUM* bn_q = OSSL::byteString2bn(params->getQ());
+ BIGNUM* bn_g = OSSL::byteString2bn(params->getG());
+ DSA_set0_pqg(dsa, bn_p, bn_q, bn_g);
+
+ if (DSA_generate_key(dsa) != 1)
+ {
+ ERROR_MSG("DSA key generation failed (0x%08X)", ERR_get_error());
+
+ DSA_free(dsa);
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ OSSLDSAKeyPair* kp = new OSSLDSAKeyPair();
+
+ ((OSSLDSAPublicKey*) kp->getPublicKey())->setFromOSSL(dsa);
+ ((OSSLDSAPrivateKey*) kp->getPrivateKey())->setFromOSSL(dsa);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ DSA_free(dsa);
+
+ return true;
+}
+
+unsigned long OSSLDSA::getMinKeySize()
+{
+#ifdef WITH_FIPS
+ // OPENSSL_DSA_FIPS_MIN_MODULUS_BITS is 1024
+ return 1024;
+#else
+ return 512;
+#endif
+}
+
+unsigned long OSSLDSA::getMaxKeySize()
+{
+ return OPENSSL_DSA_MAX_MODULUS_BITS;
+}
+
+bool OSSLDSA::generateParameters(AsymmetricParameters** ppParams, void* parameters /* = NULL */, RNG* /*rng = NULL*/)
+{
+ if ((ppParams == NULL) || (parameters == NULL))
+ {
+ return false;
+ }
+
+ size_t bitLen = (size_t) parameters;
+
+ if (bitLen < getMinKeySize() || bitLen > getMaxKeySize())
+ {
+ ERROR_MSG("This DSA key size is not supported");
+
+ return false;
+ }
+
+ DSA* dsa = DSA_new();
+
+ if (dsa == NULL ||
+ !DSA_generate_parameters_ex(dsa, bitLen, NULL, 0, NULL, NULL, NULL))
+ {
+ ERROR_MSG("Failed to generate %d bit DSA parameters", bitLen);
+
+ return false;
+ }
+
+ // Store the DSA parameters
+ DSAParameters* params = new DSAParameters();
+
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_q = NULL;
+ const BIGNUM* bn_g = NULL;
+ DSA_get0_pqg(dsa, &bn_p, &bn_q, &bn_g);
+
+ ByteString p = OSSL::bn2ByteString(bn_p); params->setP(p);
+ ByteString q = OSSL::bn2ByteString(bn_q); params->setQ(q);
+ ByteString g = OSSL::bn2ByteString(bn_g); params->setG(g);
+
+ *ppParams = params;
+
+ DSA_free(dsa);
+
+ return true;
+}
+
+bool OSSLDSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ OSSLDSAKeyPair* kp = new OSSLDSAKeyPair();
+
+ bool rv = true;
+
+ if (!((DSAPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((DSAPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool OSSLDSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLDSAPublicKey* pub = new OSSLDSAPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool OSSLDSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLDSAPrivateKey* priv = new OSSLDSAPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* OSSLDSA::newPublicKey()
+{
+ return (PublicKey*) new OSSLDSAPublicKey();
+}
+
+PrivateKey* OSSLDSA::newPrivateKey()
+{
+ return (PrivateKey*) new OSSLDSAPrivateKey();
+}
+
+AsymmetricParameters* OSSLDSA::newParameters()
+{
+ return (AsymmetricParameters*) new DSAParameters();
+}
+
+bool OSSLDSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ DSAParameters* params = new DSAParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSA.h b/SoftHSMv2/src/lib/crypto/OSSLDSA.h
new file mode 100644
index 0000000..1fb2b1e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSA.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSA.h
+
+ OpenSSL DSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDSA_H
+#define _SOFTHSM_V2_OSSLDSA_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include <openssl/dsa.h>
+
+class OSSLDSA : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ OSSLDSA();
+
+ // Destructor
+ virtual ~OSSLDSA();
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool generateParameters(AsymmetricParameters** ppParams, void* parameters = NULL, RNG* rng = NULL);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ HashAlgorithm* pCurrentHash;
+};
+
+#endif // !_SOFTHSM_V2_OSSLDSA_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.cpp b/SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.cpp
new file mode 100644
index 0000000..aba56f1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSAKeyPair.cpp
+
+ OpenSSL DSA key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLDSAKeyPair.h"
+
+// Set the public key
+void OSSLDSAKeyPair::setPublicKey(OSSLDSAPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void OSSLDSAKeyPair::setPrivateKey(OSSLDSAPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* OSSLDSAKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* OSSLDSAKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* OSSLDSAKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* OSSLDSAKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.h b/SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.h
new file mode 100644
index 0000000..6a0bdf2
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSAKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSAKeyPair.h
+
+ OpenSSL DSA key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDSAKEYPAIR_H
+#define _SOFTHSM_V2_OSSLDSAKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "OSSLDSAPublicKey.h"
+#include "OSSLDSAPrivateKey.h"
+
+class OSSLDSAKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(OSSLDSAPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(OSSLDSAPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ OSSLDSAPublicKey pubKey;
+
+ // The private key
+ OSSLDSAPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLDSAKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.cpp
new file mode 100644
index 0000000..527e041
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.cpp
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSAPrivateKey.cpp
+
+ OpenSSL DSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLComp.h"
+#include "OSSLDSAPrivateKey.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+#include <string.h>
+
+// Constructors
+OSSLDSAPrivateKey::OSSLDSAPrivateKey()
+{
+ dsa = NULL;
+}
+
+OSSLDSAPrivateKey::OSSLDSAPrivateKey(const DSA* inDSA)
+{
+ dsa = NULL;
+
+ setFromOSSL(inDSA);
+}
+
+// Destructor
+OSSLDSAPrivateKey::~OSSLDSAPrivateKey()
+{
+ DSA_free(dsa);
+}
+
+// The type
+/*static*/ const char* OSSLDSAPrivateKey::type = "OpenSSL DSA Private Key";
+
+// Set from OpenSSL representation
+void OSSLDSAPrivateKey::setFromOSSL(const DSA* inDSA)
+{
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_q = NULL;
+ const BIGNUM* bn_g = NULL;
+ const BIGNUM* bn_priv_key = NULL;
+
+ DSA_get0_pqg(inDSA, &bn_p, &bn_q, &bn_g);
+ DSA_get0_key(inDSA, NULL, &bn_priv_key);
+
+ if (bn_p)
+ {
+ ByteString inP = OSSL::bn2ByteString(bn_p);
+ setP(inP);
+ }
+ if (bn_q)
+ {
+ ByteString inQ = OSSL::bn2ByteString(bn_q);
+ setQ(inQ);
+ }
+ if (bn_g)
+ {
+ ByteString inG = OSSL::bn2ByteString(bn_g);
+ setG(inG);
+ }
+ if (bn_priv_key)
+ {
+ ByteString inX = OSSL::bn2ByteString(bn_priv_key);
+ setX(inX);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLDSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DSA private key components
+void OSSLDSAPrivateKey::setX(const ByteString& inX)
+{
+ DSAPrivateKey::setX(inX);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+
+// Setters for the DSA domain parameters
+void OSSLDSAPrivateKey::setP(const ByteString& inP)
+{
+ DSAPrivateKey::setP(inP);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+void OSSLDSAPrivateKey::setQ(const ByteString& inQ)
+{
+ DSAPrivateKey::setQ(inQ);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+void OSSLDSAPrivateKey::setG(const ByteString& inG)
+{
+ DSAPrivateKey::setG(inG);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString OSSLDSAPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ if (dsa == NULL) createOSSLKey();
+ if (dsa == NULL) return der;
+ EVP_PKEY* pkey = EVP_PKEY_new();
+ if (pkey == NULL) return der;
+ if (!EVP_PKEY_set1_DSA(pkey, dsa))
+ {
+ EVP_PKEY_free(pkey);
+ return der;
+ }
+ PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey);
+ EVP_PKEY_free(pkey);
+ if (p8inf == NULL) return der;
+ int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL);
+ if (len < 0)
+ {
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return der;
+ }
+ der.resize(len);
+ unsigned char* priv = &der[0];
+ int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (len2 != len) der.wipe();
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool OSSLDSAPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ int len = ber.size();
+ if (len <= 0) return false;
+ const unsigned char* priv = ber.const_byte_str();
+ PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &priv, len);
+ if (p8 == NULL) return false;
+ EVP_PKEY* pkey = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (pkey == NULL) return false;
+ DSA* key = EVP_PKEY_get1_DSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (key == NULL) return false;
+ setFromOSSL(key);
+ DSA_free(key);
+ return true;
+}
+
+// Retrieve the OpenSSL representation of the key
+DSA* OSSLDSAPrivateKey::getOSSLKey()
+{
+ if (dsa == NULL) createOSSLKey();
+
+ return dsa;
+}
+
+// Create the OpenSSL representation of the key
+void OSSLDSAPrivateKey::createOSSLKey()
+{
+ if (dsa != NULL) return;
+
+ BN_CTX *ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ ERROR_MSG("Could not create BN_CTX");
+ return;
+ }
+
+ dsa = DSA_new();
+ if (dsa == NULL)
+ {
+ ERROR_MSG("Could not create DSA object");
+ return;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ DSA_set_method(dsa, FIPS_dsa_openssl());
+ else
+ DSA_set_method(dsa, DSA_OpenSSL());
+#else
+ DSA_set_method(dsa, DSA_OpenSSL());
+#endif
+
+#else
+ DSA_set_method(dsa, DSA_OpenSSL());
+#endif
+
+ BIGNUM* bn_p = OSSL::byteString2bn(p);
+ BIGNUM* bn_q = OSSL::byteString2bn(q);
+ BIGNUM* bn_g = OSSL::byteString2bn(g);
+ BIGNUM* bn_priv_key = OSSL::byteString2bn(x);
+ BIGNUM* bn_pub_key = BN_new();
+
+ BN_mod_exp(bn_pub_key, bn_g, bn_priv_key, bn_p, ctx);
+ BN_CTX_free(ctx);
+
+ DSA_set0_pqg(dsa, bn_p, bn_q, bn_g);
+ DSA_set0_key(dsa, bn_pub_key, bn_priv_key);
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.h
new file mode 100644
index 0000000..0e7a9ef
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSAPrivateKey.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSAPrivateKey.h
+
+ OpenSSL DSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDSAPRIVATEKEY_H
+#define _SOFTHSM_V2_OSSLDSAPRIVATEKEY_H
+
+#include "config.h"
+#include "DSAPrivateKey.h"
+#include <openssl/dsa.h>
+
+class OSSLDSAPrivateKey : public DSAPrivateKey
+{
+public:
+ // Constructors
+ OSSLDSAPrivateKey();
+
+ OSSLDSAPrivateKey(const DSA* inDSA);
+
+ // Destructor
+ virtual ~OSSLDSAPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DSA private key components
+ virtual void setX(const ByteString& inX);
+
+ // Setters for the DSA domain parameters
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setG(const ByteString& inG);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const DSA* inDSA);
+
+ // Retrieve the OpenSSL representation of the key
+ DSA* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ DSA* dsa;
+
+ // Create the OpenSSL representation of the key
+ void createOSSLKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLDSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.cpp
new file mode 100644
index 0000000..38ecc79
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSAPublicKey.cpp
+
+ OpenSSL DSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLDSAPublicKey.h"
+#include "OSSLComp.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+#include <string.h>
+
+// Constructors
+OSSLDSAPublicKey::OSSLDSAPublicKey()
+{
+ dsa = NULL;
+}
+
+OSSLDSAPublicKey::OSSLDSAPublicKey(const DSA* inDSA)
+{
+ dsa = NULL;
+
+ setFromOSSL(inDSA);
+}
+
+// Destructor
+OSSLDSAPublicKey::~OSSLDSAPublicKey()
+{
+ DSA_free(dsa);
+}
+
+// The type
+/*static*/ const char* OSSLDSAPublicKey::type = "OpenSSL DSA Public Key";
+
+// Set from OpenSSL representation
+void OSSLDSAPublicKey::setFromOSSL(const DSA* inDSA)
+{
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_q = NULL;
+ const BIGNUM* bn_g = NULL;
+ const BIGNUM* bn_pub_key = NULL;
+
+ DSA_get0_pqg(inDSA, &bn_p, &bn_q, &bn_g);
+ DSA_get0_key(inDSA, &bn_pub_key, NULL);
+
+ if (bn_p)
+ {
+ ByteString inP = OSSL::bn2ByteString(bn_p);
+ setP(inP);
+ }
+ if (bn_q)
+ {
+ ByteString inQ = OSSL::bn2ByteString(bn_q);
+ setQ(inQ);
+ }
+ if (bn_g)
+ {
+ ByteString inG = OSSL::bn2ByteString(bn_g);
+ setG(inG);
+ }
+ if (bn_pub_key)
+ {
+ ByteString inY = OSSL::bn2ByteString(bn_pub_key);
+ setY(inY);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLDSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the DSA public key components
+void OSSLDSAPublicKey::setP(const ByteString& inP)
+{
+ DSAPublicKey::setP(inP);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+void OSSLDSAPublicKey::setQ(const ByteString& inQ)
+{
+ DSAPublicKey::setQ(inQ);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+void OSSLDSAPublicKey::setG(const ByteString& inG)
+{
+ DSAPublicKey::setG(inG);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+void OSSLDSAPublicKey::setY(const ByteString& inY)
+{
+ DSAPublicKey::setY(inY);
+
+ if (dsa)
+ {
+ DSA_free(dsa);
+ dsa = NULL;
+ }
+}
+
+// Retrieve the OpenSSL representation of the key
+DSA* OSSLDSAPublicKey::getOSSLKey()
+{
+ if (dsa == NULL) createOSSLKey();
+
+ return dsa;
+}
+
+// Create the OpenSSL representation of the key
+void OSSLDSAPublicKey::createOSSLKey()
+{
+ if (dsa != NULL) return;
+
+ dsa = DSA_new();
+ if (dsa == NULL)
+ {
+ ERROR_MSG("Could not create DSA object");
+ return;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ DSA_set_method(dsa, FIPS_dsa_openssl());
+ else
+ DSA_set_method(dsa, DSA_OpenSSL());
+#else
+ DSA_set_method(dsa, DSA_OpenSSL());
+#endif
+
+#else
+ DSA_set_method(dsa, DSA_OpenSSL());
+#endif
+
+ BIGNUM* bn_p = OSSL::byteString2bn(p);
+ BIGNUM* bn_q = OSSL::byteString2bn(q);
+ BIGNUM* bn_g = OSSL::byteString2bn(g);
+ BIGNUM* bn_pub_key = OSSL::byteString2bn(y);
+
+ DSA_set0_pqg(dsa, bn_p, bn_q, bn_g);
+ DSA_set0_key(dsa, bn_pub_key, NULL);
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.h b/SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.h
new file mode 100644
index 0000000..b30d05c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLDSAPublicKey.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLDSAPublicKey.h
+
+ OpenSSL DSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLDSAPUBLICKEY_H
+#define _SOFTHSM_V2_OSSLDSAPUBLICKEY_H
+
+#include "config.h"
+#include "DSAPublicKey.h"
+#include <openssl/dsa.h>
+
+class OSSLDSAPublicKey : public DSAPublicKey
+{
+public:
+ // Constructors
+ OSSLDSAPublicKey();
+
+ OSSLDSAPublicKey(const DSA* inDSA);
+
+ // Destructor
+ virtual ~OSSLDSAPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the DSA public key components
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setG(const ByteString& inG);
+ virtual void setY(const ByteString& inY);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const DSA* inDSA);
+
+ // Retrieve the OpenSSL representation of the key
+ DSA* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ DSA* dsa;
+
+ // Create the OpenSSL representation of the key
+ void createOSSLKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLDSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECDH.cpp b/SoftHSMv2/src/lib/crypto/OSSLECDH.cpp
new file mode 100644
index 0000000..e2abaeb
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECDH.cpp
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECDH.cpp
+
+ OpenSSL Diffie-Hellman asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "OSSLECDH.h"
+#include "CryptoFactory.h"
+#include "ECParameters.h"
+#include "OSSLECKeyPair.h"
+#include "OSSLUtil.h"
+#include <algorithm>
+#include <openssl/ecdh.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+
+// Signing functions
+bool OSSLECDH::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDH does not support signing");
+
+ return false;
+}
+
+bool OSSLECDH::signUpdate(const ByteString& /*dataToSign*/)
+{
+ ERROR_MSG("ECDH does not support signing");
+
+ return false;
+}
+
+bool OSSLECDH::signFinal(ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDH does not support signing");
+
+ return false;
+}
+
+// Verification functions
+bool OSSLECDH::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDH does not support verifying");
+
+ return false;
+}
+
+bool OSSLECDH::verifyUpdate(const ByteString& /*originalData*/)
+{
+ ERROR_MSG("ECDH does not support verifying");
+
+ return false;
+}
+
+bool OSSLECDH::verifyFinal(const ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDH does not support verifying");
+
+ return false;
+}
+
+// Encryption functions
+bool OSSLECDH::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDH does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool OSSLECDH::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDH does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool OSSLECDH::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(ECParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for ECDH key generation");
+
+ return false;
+ }
+
+ ECParameters* params = (ECParameters*) parameters;
+
+ // Generate the key-pair
+ EC_KEY* eckey = EC_KEY_new();
+
+ if (eckey == NULL)
+ {
+ ERROR_MSG("Failed to instantiate OpenSSL ECDH object");
+
+ return false;
+ }
+
+ EC_GROUP* grp = OSSL::byteString2grp(params->getEC());
+ EC_KEY_set_group(eckey, grp);
+ EC_GROUP_free(grp);
+
+ if (!EC_KEY_generate_key(eckey))
+ {
+ ERROR_MSG("ECDH key generation failed (0x%08X)", ERR_get_error());
+
+ EC_KEY_free(eckey);
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ OSSLECKeyPair* kp = new OSSLECKeyPair();
+
+ ((OSSLECPublicKey*) kp->getPublicKey())->setFromOSSL(eckey);
+ ((OSSLECPrivateKey*) kp->getPrivateKey())->setFromOSSL(eckey);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ EC_KEY_free(eckey);
+
+ return true;
+}
+
+bool OSSLECDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
+{
+ // Check parameters
+ if ((ppSymmetricKey == NULL) ||
+ (publicKey == NULL) ||
+ (privateKey == NULL))
+ {
+ return false;
+ }
+
+ // Get keys
+ EC_KEY *pub = ((OSSLECPublicKey *)publicKey)->getOSSLKey();
+ EC_KEY *priv = ((OSSLECPrivateKey *)privateKey)->getOSSLKey();
+ if (pub == NULL || EC_KEY_get0_public_key(pub) == NULL || priv == NULL)
+ {
+ ERROR_MSG("Failed to get OpenSSL ECDH keys");
+
+ return false;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ {
+ ECDH_set_method(pub, FIPS_ecdh_openssl());
+ ECDH_set_method(priv, FIPS_ecdh_openssl());
+ }
+ else
+ {
+ ECDH_set_method(pub, ECDH_OpenSSL());
+ ECDH_set_method(priv, ECDH_OpenSSL());
+ }
+#else
+ ECDH_set_method(pub, ECDH_OpenSSL());
+ ECDH_set_method(priv, ECDH_OpenSSL());
+#endif
+
+#else
+ EC_KEY_set_method(pub, EC_KEY_OpenSSL());
+ EC_KEY_set_method(priv, EC_KEY_OpenSSL());
+#endif
+
+ // Derive the secret
+ ByteString secret, derivedSecret;
+ int size = ((OSSLECPublicKey *)publicKey)->getOrderLength();
+ secret.wipe(size);
+ derivedSecret.wipe(size);
+ int keySize = ECDH_compute_key(&derivedSecret[0], derivedSecret.size(), EC_KEY_get0_public_key(pub), priv, NULL);
+
+ if (keySize <= 0)
+ {
+ ERROR_MSG("ECDH key derivation failed (0x%08X)", ERR_get_error());
+
+ return false;
+ }
+
+ // We compensate that OpenSSL removes leading zeros
+ memcpy(&secret[0] + size - keySize, &derivedSecret[0], keySize);
+
+ *ppSymmetricKey = new SymmetricKey(secret.size() * 8);
+ if (*ppSymmetricKey == NULL)
+ return false;
+ if (!(*ppSymmetricKey)->setKeyBits(secret))
+ {
+ delete *ppSymmetricKey;
+ *ppSymmetricKey = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+unsigned long OSSLECDH::getMinKeySize()
+{
+ // Smallest EC group is secp112r1
+ return 112;
+}
+
+unsigned long OSSLECDH::getMaxKeySize()
+{
+ // Biggest EC group is secp521r1
+ return 521;
+}
+
+bool OSSLECDH::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ OSSLECKeyPair* kp = new OSSLECKeyPair();
+
+ bool rv = true;
+
+ if (!((ECPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((ECPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool OSSLECDH::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLECPublicKey* pub = new OSSLECPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool OSSLECDH::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLECPrivateKey* priv = new OSSLECPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* OSSLECDH::newPublicKey()
+{
+ return (PublicKey*) new OSSLECPublicKey();
+}
+
+PrivateKey* OSSLECDH::newPrivateKey()
+{
+ return (PrivateKey*) new OSSLECPrivateKey();
+}
+
+AsymmetricParameters* OSSLECDH::newParameters()
+{
+ return (AsymmetricParameters*) new ECParameters();
+}
+
+bool OSSLECDH::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ECParameters* params = new ECParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECDH.h b/SoftHSMv2/src/lib/crypto/OSSLECDH.h
new file mode 100644
index 0000000..2cafa6f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECDH.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECDH.h
+
+ OpenSSL ECDH asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLECDH_H
+#define _SOFTHSM_V2_OSSLECDH_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <openssl/ecdh.h>
+
+class OSSLECDH : public AsymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~OSSLECDH() { }
+
+ // Signing functions
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey);
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_OSSLECDH_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECDSA.cpp b/SoftHSMv2/src/lib/crypto/OSSLECDSA.cpp
new file mode 100644
index 0000000..7387367
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECDSA.cpp
@@ -0,0 +1,457 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECDSA.cpp
+
+ OpenSSL ECDSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "OSSLECDSA.h"
+#include "CryptoFactory.h"
+#include "ECParameters.h"
+#include "OSSLECKeyPair.h"
+#include "OSSLComp.h"
+#include "OSSLUtil.h"
+#include <algorithm>
+#include <openssl/ecdsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+#include <string.h>
+
+// Signing functions
+bool OSSLECDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ if (mechanism != AsymMech::ECDSA)
+ {
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLECPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ OSSLECPrivateKey* pk = (OSSLECPrivateKey*) privateKey;
+ EC_KEY* eckey = pk->getOSSLKey();
+
+ if (eckey == NULL)
+ {
+ ERROR_MSG("Could not get the OpenSSL private key");
+
+ return false;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ ECDSA_set_method(eckey, FIPS_ecdsa_openssl());
+ else
+ ECDSA_set_method(eckey, ECDSA_OpenSSL());
+#else
+ ECDSA_set_method(eckey, ECDSA_OpenSSL());
+#endif
+
+#else
+ EC_KEY_set_method(eckey, EC_KEY_OpenSSL());
+#endif
+
+ // Perform the signature operation
+ size_t len = pk->getOrderLength();
+ if (len == 0)
+ {
+ ERROR_MSG("Could not get the order length");
+ return false;
+ }
+ signature.resize(2 * len);
+ memset(&signature[0], 0, 2 * len);
+ ECDSA_SIG *sig = ECDSA_do_sign(dataToSign.const_byte_str(), dataToSign.size(), eckey);
+ if (sig == NULL)
+ {
+ ERROR_MSG("ECDSA sign failed (0x%08X)", ERR_get_error());
+ return false;
+ }
+ // Store the 2 values with padding
+ const BIGNUM* bn_r = NULL;
+ const BIGNUM* bn_s = NULL;
+ ECDSA_SIG_get0(sig, &bn_r, &bn_s);
+ BN_bn2bin(bn_r, &signature[len - BN_num_bytes(bn_r)]);
+ BN_bn2bin(bn_s, &signature[2 * len - BN_num_bytes(bn_s)]);
+ ECDSA_SIG_free(sig);
+ return true;
+}
+
+bool OSSLECDSA::signInit(PrivateKey* /*privateKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDSA does not support multi part signing");
+
+ return false;
+}
+
+bool OSSLECDSA::signUpdate(const ByteString& /*dataToSign*/)
+{
+ ERROR_MSG("ECDSA does not support multi part signing");
+
+ return false;
+}
+
+bool OSSLECDSA::signFinal(ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDSA does not support multi part signing");
+
+ return false;
+}
+
+// Verification functions
+bool OSSLECDSA::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ if (mechanism != AsymMech::ECDSA)
+ {
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!publicKey->isOfType(OSSLECPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ OSSLECPublicKey* pk = (OSSLECPublicKey*) publicKey;
+ EC_KEY* eckey = pk->getOSSLKey();
+
+ if (eckey == NULL)
+ {
+ ERROR_MSG("Could not get the OpenSSL public key");
+
+ return false;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ ECDSA_set_method(eckey, FIPS_ecdsa_openssl());
+ else
+ ECDSA_set_method(eckey, ECDSA_OpenSSL());
+#else
+ ECDSA_set_method(eckey, ECDSA_OpenSSL());
+#endif
+
+#else
+ EC_KEY_set_method(eckey, EC_KEY_OpenSSL());
+#endif
+
+ // Perform the verify operation
+ size_t len = pk->getOrderLength();
+ if (len == 0)
+ {
+ ERROR_MSG("Could not get the order length");
+ return false;
+ }
+ if (signature.size() != 2 * len)
+ {
+ ERROR_MSG("Invalid buffer length");
+ return false;
+ }
+ ECDSA_SIG* sig = ECDSA_SIG_new();
+ if (sig == NULL)
+ {
+ ERROR_MSG("Could not create an ECDSA_SIG object");
+ return false;
+ }
+ const unsigned char *s = signature.const_byte_str();
+ BIGNUM* bn_r = BN_bin2bn(s, len, NULL);
+ BIGNUM* bn_s = BN_bin2bn(s + len, len, NULL);
+ if (bn_r == NULL || bn_s == NULL ||
+ !ECDSA_SIG_set0(sig, bn_r, bn_s))
+ {
+ ERROR_MSG("Could not add data to the ECDSA_SIG object");
+ ECDSA_SIG_free(sig);
+ return false;
+ }
+ int ret = ECDSA_do_verify(originalData.const_byte_str(), originalData.size(), sig, eckey);
+ if (ret != 1)
+ {
+ if (ret < 0)
+ ERROR_MSG("ECDSA verify failed (0x%08X)", ERR_get_error());
+
+ ECDSA_SIG_free(sig);
+ return false;
+ }
+
+ ECDSA_SIG_free(sig);
+ return true;
+}
+
+bool OSSLECDSA::verifyInit(PublicKey* /*publicKey*/, const AsymMech::Type /*mechanism*/,
+ const void* /* param = NULL */, const size_t /* paramLen = 0 */)
+{
+ ERROR_MSG("ECDSA does not support multi part verifying");
+
+ return false;
+}
+
+bool OSSLECDSA::verifyUpdate(const ByteString& /*originalData*/)
+{
+ ERROR_MSG("ECDSA does not support multi part verifying");
+
+ return false;
+}
+
+bool OSSLECDSA::verifyFinal(const ByteString& /*signature*/)
+{
+ ERROR_MSG("ECDSA does not support multi part verifying");
+
+ return false;
+}
+
+// Encryption functions
+bool OSSLECDSA::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDSA does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool OSSLECDSA::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("ECDSA does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool OSSLECDSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(ECParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for ECDSA key generation");
+
+ return false;
+ }
+
+ ECParameters* params = (ECParameters*) parameters;
+
+ // Generate the key-pair
+ EC_KEY* eckey = EC_KEY_new();
+ if (eckey == NULL)
+ {
+ ERROR_MSG("Failed to instantiate OpenSSL ECDSA object");
+
+ return false;
+ }
+
+ EC_GROUP* grp = OSSL::byteString2grp(params->getEC());
+ EC_KEY_set_group(eckey, grp);
+ EC_GROUP_free(grp);
+
+ if (!EC_KEY_generate_key(eckey))
+ {
+ ERROR_MSG("ECDSA key generation failed (0x%08X)", ERR_get_error());
+
+ EC_KEY_free(eckey);
+
+ return false;
+ }
+
+ // Create an asymmetric key-pair object to return
+ OSSLECKeyPair* kp = new OSSLECKeyPair();
+
+ ((OSSLECPublicKey*) kp->getPublicKey())->setFromOSSL(eckey);
+ ((OSSLECPrivateKey*) kp->getPrivateKey())->setFromOSSL(eckey);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ EC_KEY_free(eckey);
+
+ return true;
+}
+
+unsigned long OSSLECDSA::getMinKeySize()
+{
+ // Smallest EC group is secp112r1
+ return 112;
+}
+
+unsigned long OSSLECDSA::getMaxKeySize()
+{
+ // Biggest EC group is secp521r1
+ return 521;
+}
+
+bool OSSLECDSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ OSSLECKeyPair* kp = new OSSLECKeyPair();
+
+ bool rv = true;
+
+ if (!((ECPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((ECPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool OSSLECDSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLECPublicKey* pub = new OSSLECPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool OSSLECDSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLECPrivateKey* priv = new OSSLECPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* OSSLECDSA::newPublicKey()
+{
+ return (PublicKey*) new OSSLECPublicKey();
+}
+
+PrivateKey* OSSLECDSA::newPrivateKey()
+{
+ return (PrivateKey*) new OSSLECPrivateKey();
+}
+
+AsymmetricParameters* OSSLECDSA::newParameters()
+{
+ return (AsymmetricParameters*) new ECParameters();
+}
+
+bool OSSLECDSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ECParameters* params = new ECParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECDSA.h b/SoftHSMv2/src/lib/crypto/OSSLECDSA.h
new file mode 100644
index 0000000..992fa40
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECDSA.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECDSA.h
+
+ OpenSSL ECDSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLECDSA_H
+#define _SOFTHSM_V2_OSSLECDSA_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <openssl/ecdsa.h>
+
+class OSSLECDSA : public AsymmetricAlgorithm
+{
+public:
+ // Destructor
+ virtual ~OSSLECDSA() { }
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_OSSLECDSA_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECKeyPair.cpp b/SoftHSMv2/src/lib/crypto/OSSLECKeyPair.cpp
new file mode 100644
index 0000000..2e55f8f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECKeyPair.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECKeyPair.cpp
+
+ OpenSSL Elliptic Curve key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "OSSLECKeyPair.h"
+
+// Set the public key
+void OSSLECKeyPair::setPublicKey(OSSLECPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void OSSLECKeyPair::setPrivateKey(OSSLECPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* OSSLECKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* OSSLECKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* OSSLECKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* OSSLECKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECKeyPair.h b/SoftHSMv2/src/lib/crypto/OSSLECKeyPair.h
new file mode 100644
index 0000000..ada9b8d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECKeyPair.h
+
+ OpenSSL Elliptic Curve key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLECKEYPAIR_H
+#define _SOFTHSM_V2_OSSLECKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "OSSLECPublicKey.h"
+#include "OSSLECPrivateKey.h"
+
+class OSSLECKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(OSSLECPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(OSSLECPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ OSSLECPublicKey pubKey;
+
+ // The private key
+ OSSLECPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLECKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.cpp
new file mode 100644
index 0000000..4f6b055
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.cpp
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECPrivateKey.cpp
+
+ OpenSSL EC private key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "OSSLECPrivateKey.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+
+// Constructors
+OSSLECPrivateKey::OSSLECPrivateKey()
+{
+ eckey = EC_KEY_new();
+
+ // For PKCS#8 encoding
+ EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
+}
+
+OSSLECPrivateKey::OSSLECPrivateKey(const EC_KEY* inECKEY)
+{
+ eckey = EC_KEY_new();
+
+ // For PKCS#8 encoding
+ EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
+
+ setFromOSSL(inECKEY);
+}
+
+// Destructor
+OSSLECPrivateKey::~OSSLECPrivateKey()
+{
+ EC_KEY_free(eckey);
+}
+
+// The type
+/*static*/ const char* OSSLECPrivateKey::type = "OpenSSL EC Private Key";
+
+// Get the base point order length
+unsigned long OSSLECPrivateKey::getOrderLength() const
+{
+ const EC_GROUP* grp = EC_KEY_get0_group(eckey);
+ if (grp != NULL)
+ {
+ BIGNUM* order = BN_new();
+ if (order == NULL)
+ return 0;
+ if (!EC_GROUP_get_order(grp, order, NULL))
+ {
+ BN_clear_free(order);
+ return 0;
+ }
+ unsigned long len = BN_num_bytes(order);
+ BN_clear_free(order);
+ return len;
+ }
+ return 0;
+}
+
+// Set from OpenSSL representation
+void OSSLECPrivateKey::setFromOSSL(const EC_KEY* inECKEY)
+{
+ const EC_GROUP* grp = EC_KEY_get0_group(inECKEY);
+ if (grp != NULL)
+ {
+ ByteString inEC = OSSL::grp2ByteString(grp);
+ setEC(inEC);
+ }
+ const BIGNUM* pk = EC_KEY_get0_private_key(inECKEY);
+ if (pk != NULL)
+ {
+ ByteString inD = OSSL::bn2ByteString(pk);
+ setD(inD);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLECPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the EC private key components
+void OSSLECPrivateKey::setD(const ByteString& inD)
+{
+ ECPrivateKey::setD(inD);
+
+ BIGNUM* pk = OSSL::byteString2bn(inD);
+ EC_KEY_set_private_key(eckey, pk);
+ BN_clear_free(pk);
+}
+
+
+// Setters for the EC public key components
+void OSSLECPrivateKey::setEC(const ByteString& inEC)
+{
+ ECPrivateKey::setEC(inEC);
+
+ EC_GROUP* grp = OSSL::byteString2grp(inEC);
+ EC_KEY_set_group(eckey, grp);
+ EC_GROUP_free(grp);
+}
+
+// Encode into PKCS#8 DER
+ByteString OSSLECPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ if (eckey == NULL) return der;
+ EVP_PKEY* pkey = EVP_PKEY_new();
+ if (pkey == NULL) return der;
+ if (!EVP_PKEY_set1_EC_KEY(pkey, eckey))
+ {
+ EVP_PKEY_free(pkey);
+ return der;
+ }
+ PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey);
+ EVP_PKEY_free(pkey);
+ if (p8inf == NULL) return der;
+ int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL);
+ if (len < 0)
+ {
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return der;
+ }
+ der.resize(len);
+ unsigned char* priv = &der[0];
+ int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (len2 != len) der.wipe();
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool OSSLECPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ int len = ber.size();
+ if (len <= 0) return false;
+ const unsigned char* priv = ber.const_byte_str();
+ PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &priv, len);
+ if (p8 == NULL) return false;
+ EVP_PKEY* pkey = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (pkey == NULL) return false;
+ EC_KEY* key = EVP_PKEY_get1_EC_KEY(pkey);
+ EVP_PKEY_free(pkey);
+ if (key == NULL) return false;
+ setFromOSSL(key);
+ EC_KEY_free(key);
+ return true;
+}
+
+// Retrieve the OpenSSL representation of the key
+EC_KEY* OSSLECPrivateKey::getOSSLKey()
+{
+ return eckey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.h b/SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.h
new file mode 100644
index 0000000..152ad03
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECPrivateKey.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECPrivateKey.h
+
+ OpenSSL Elliptic Curve private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLECPRIVATEKEY_H
+#define _SOFTHSM_V2_OSSLECPRIVATEKEY_H
+
+#include "config.h"
+#include "ECPrivateKey.h"
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+
+class OSSLECPrivateKey : public ECPrivateKey
+{
+public:
+ // Constructors
+ OSSLECPrivateKey();
+
+ OSSLECPrivateKey(const EC_KEY* inECKEY);
+
+ // Destructor
+ virtual ~OSSLECPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the EC private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the EC public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const EC_KEY* inECKEY);
+
+ // Retrieve the OpenSSL representation of the key
+ EC_KEY* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ EC_KEY* eckey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLECPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECPublicKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLECPublicKey.cpp
new file mode 100644
index 0000000..b2d80af
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECPublicKey.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECPublicKey.cpp
+
+ OpenSSL Elliptic Curve public key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_ECC
+#include "log.h"
+#include "OSSLECPublicKey.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#include <string.h>
+
+// Constructors
+OSSLECPublicKey::OSSLECPublicKey()
+{
+ eckey = EC_KEY_new();
+}
+
+OSSLECPublicKey::OSSLECPublicKey(const EC_KEY* inECKEY)
+{
+ eckey = EC_KEY_new();
+
+ setFromOSSL(inECKEY);
+}
+
+// Destructor
+OSSLECPublicKey::~OSSLECPublicKey()
+{
+ EC_KEY_free(eckey);
+}
+
+// The type
+/*static*/ const char* OSSLECPublicKey::type = "OpenSSL EC Public Key";
+
+// Get the base point order length
+unsigned long OSSLECPublicKey::getOrderLength() const
+{
+ const EC_GROUP* grp = EC_KEY_get0_group(eckey);
+ if (grp != NULL)
+ {
+ BIGNUM* order = BN_new();
+ if (order == NULL)
+ return 0;
+ if (!EC_GROUP_get_order(grp, order, NULL))
+ {
+ BN_clear_free(order);
+ return 0;
+ }
+ unsigned long len = BN_num_bytes(order);
+ BN_clear_free(order);
+ return len;
+ }
+ return 0;
+}
+
+// Set from OpenSSL representation
+void OSSLECPublicKey::setFromOSSL(const EC_KEY* inECKEY)
+{
+ const EC_GROUP* grp = EC_KEY_get0_group(inECKEY);
+ if (grp != NULL)
+ {
+ ByteString inEC = OSSL::grp2ByteString(grp);
+ setEC(inEC);
+ }
+ const EC_POINT* pub = EC_KEY_get0_public_key(inECKEY);
+ if (pub != NULL && grp != NULL)
+ {
+ ByteString inQ = OSSL::pt2ByteString(pub, grp);
+ setQ(inQ);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLECPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the EC public key components
+void OSSLECPublicKey::setEC(const ByteString& inEC)
+{
+ ECPublicKey::setEC(inEC);
+
+ EC_GROUP* grp = OSSL::byteString2grp(inEC);
+ EC_KEY_set_group(eckey, grp);
+ EC_GROUP_free(grp);
+}
+
+void OSSLECPublicKey::setQ(const ByteString& inQ)
+{
+ ECPublicKey::setQ(inQ);
+
+ EC_POINT* pub = OSSL::byteString2pt(inQ, EC_KEY_get0_group(eckey));
+ EC_KEY_set_public_key(eckey, pub);
+ EC_POINT_free(pub);
+}
+
+// Retrieve the OpenSSL representation of the key
+EC_KEY* OSSLECPublicKey::getOSSLKey()
+{
+ return eckey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLECPublicKey.h b/SoftHSMv2/src/lib/crypto/OSSLECPublicKey.h
new file mode 100644
index 0000000..3fb4f35
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLECPublicKey.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLECPublicKey.h
+
+ OpenSSL Elliptic Curve public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLECPUBLICKEY_H
+#define _SOFTHSM_V2_OSSLECPUBLICKEY_H
+
+#include "config.h"
+#include "ECPublicKey.h"
+#include <openssl/ec.h>
+
+class OSSLECPublicKey : public ECPublicKey
+{
+public:
+ // Constructors
+ OSSLECPublicKey();
+
+ OSSLECPublicKey(const EC_KEY* inECKEY);
+
+ // Destructor
+ virtual ~OSSLECPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the base point order length
+ virtual unsigned long getOrderLength() const;
+
+ // Setters for the EC public key components
+ virtual void setEC(const ByteString& inEC);
+ virtual void setQ(const ByteString& inQ);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const EC_KEY* inECKEY);
+
+ // Retrieve the OpenSSL representation of the key
+ EC_KEY* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ EC_KEY* eckey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLDSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.cpp
new file mode 100644
index 0000000..27e29d9
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2017 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// TODO: Store context in securely allocated memory
+
+/*****************************************************************************
+ OSSLEVPCMacAlgorithm.cpp
+
+ OpenSSL CMAC algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLEVPCMacAlgorithm.h"
+#include "OSSLComp.h"
+#include <openssl/err.h>
+
+// Destructor
+OSSLEVPCMacAlgorithm::~OSSLEVPCMacAlgorithm()
+{
+ if (curCTX != NULL)
+ CMAC_CTX_free(curCTX);
+}
+
+// Signing functions
+bool OSSLEVPCMacAlgorithm::signInit(const SymmetricKey* key)
+{
+ // Call the superclass initialiser
+ if (!MacAlgorithm::signInit(key))
+ {
+ return false;
+ }
+
+ // Determine the cipher class
+ const EVP_CIPHER* cipher = getEVPCipher();
+ if (cipher == NULL)
+ {
+ ERROR_MSG("Invalid sign mac algorithm");
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ // Initialize the context
+ curCTX = CMAC_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for CMAC_CTX");
+
+ return false;
+ }
+
+ // Initialize EVP signing
+ if (!CMAC_Init(curCTX, key->getKeyBits().const_byte_str(), key->getKeyBits().size(), cipher, NULL))
+ {
+ ERROR_MSG("CMAC_Init failed: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPCMacAlgorithm::signUpdate(const ByteString& dataToSign)
+{
+ if (!MacAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ if (dataToSign.size() == 0) return true;
+
+ if (!CMAC_Update(curCTX, dataToSign.const_byte_str(), dataToSign.size()))
+ {
+ ERROR_MSG("CMAC_Update failed");
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPCMacAlgorithm::signFinal(ByteString& signature)
+{
+ if (!MacAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ size_t outLen = getMacSize();
+ signature.resize(outLen);
+
+ if (!CMAC_Final(curCTX, &signature[0], &outLen))
+ {
+ ERROR_MSG("CMAC_Final failed");
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ signature.resize(outLen);
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool OSSLEVPCMacAlgorithm::verifyInit(const SymmetricKey* key)
+{
+ // Call the superclass initialiser
+ if (!MacAlgorithm::verifyInit(key))
+ {
+ return false;
+ }
+
+ // Determine the cipher class
+ const EVP_CIPHER* cipher = getEVPCipher();
+ if (cipher == NULL)
+ {
+ ERROR_MSG("Invalid verify mac algorithm");
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ // Initialize the context
+ curCTX = CMAC_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for CMAC_CTX");
+
+ return false;
+ }
+
+ // Initialize EVP signing
+ if (!CMAC_Init(curCTX, key->getKeyBits().const_byte_str(), key->getKeyBits().size(), cipher, NULL))
+ {
+ ERROR_MSG("CMAC_Init failed: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPCMacAlgorithm::verifyUpdate(const ByteString& originalData)
+{
+ if (!MacAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ if (originalData.size() == 0) return true;
+
+ if (!CMAC_Update(curCTX, originalData.const_byte_str(), originalData.size()))
+ {
+ ERROR_MSG("CMAC_Update failed");
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPCMacAlgorithm::verifyFinal(ByteString& signature)
+{
+ if (!MacAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ ByteString macResult;
+ size_t outLen = getMacSize();
+ macResult.resize(outLen);
+
+ if (!CMAC_Final(curCTX, &macResult[0], &outLen))
+ {
+ ERROR_MSG("CMAC_Final failed");
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ CMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return macResult == signature;
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.h b/SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.h
new file mode 100644
index 0000000..621e995
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPCMacAlgorithm.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLEVPCMacAlgorithm.h
+
+ OpenSSL CMAC algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLEVPCMACALGORITHM_H
+#define _SOFTHSM_V2_OSSLEVPCMACALGORITHM_H
+
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "MacAlgorithm.h"
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+
+class OSSLEVPCMacAlgorithm : public MacAlgorithm
+{
+public:
+ // Constructor
+ OSSLEVPCMacAlgorithm() {
+ curCTX = NULL;
+ };
+
+ // Destructor
+ ~OSSLEVPCMacAlgorithm();
+
+ // Signing functions
+ virtual bool signInit(const SymmetricKey* key);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(const SymmetricKey* key);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(ByteString& signature);
+
+ // Return the MAC size
+ virtual size_t getMacSize() const = 0;
+
+protected:
+ // Return the right cipher for the operation
+ virtual const EVP_CIPHER* getEVPCipher() const = 0;
+
+private:
+ // The current context
+ CMAC_CTX* curCTX;
+};
+
+#endif // !_SOFTHSM_V2_OSSLEVPCMACALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.cpp
new file mode 100644
index 0000000..a1b4f73
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLEVPHashAlgorithm.cpp
+
+ Base class for OpenSSL hash algorithm classes
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include "OSSLComp.h"
+
+// Destructor
+OSSLEVPHashAlgorithm::~OSSLEVPHashAlgorithm()
+{
+ EVP_MD_CTX_free(curCTX);
+}
+
+// Hashing functions
+bool OSSLEVPHashAlgorithm::hashInit()
+{
+ if (!HashAlgorithm::hashInit())
+ {
+ return false;
+ }
+
+ // Initialize the context
+ curCTX = EVP_MD_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for EVP_MD_CTX");
+
+ return false;
+ }
+
+ // Initialize EVP digesting
+ if (!EVP_DigestInit_ex(curCTX, getEVPHash(), NULL))
+ {
+ ERROR_MSG("EVP_DigestInit failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ HashAlgorithm::hashFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPHashAlgorithm::hashUpdate(const ByteString& data)
+{
+ if (!HashAlgorithm::hashUpdate(data))
+ {
+ return false;
+ }
+
+ // Continue digesting
+ if (data.size() == 0)
+ {
+ return true;
+ }
+
+ if (!EVP_DigestUpdate(curCTX, (unsigned char*) data.const_byte_str(), data.size()))
+ {
+ ERROR_MSG("EVP_DigestUpdate failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ HashAlgorithm::hashFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPHashAlgorithm::hashFinal(ByteString& hashedData)
+{
+ if (!HashAlgorithm::hashFinal(hashedData))
+ {
+ return false;
+ }
+
+ hashedData.resize(EVP_MD_size(getEVPHash()));
+ unsigned int outLen = hashedData.size();
+
+ if (!EVP_DigestFinal_ex(curCTX, &hashedData[0], &outLen))
+ {
+ ERROR_MSG("EVP_DigestFinal failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ hashedData.resize(outLen);
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.h b/SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.h
new file mode 100644
index 0000000..1775df2
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPHashAlgorithm.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLEVPHashAlgorithm.h
+
+ Base class for OpenSSL hash algorithm classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLEVPHASHALGORITHM_H
+#define _SOFTHSM_V2_OSSLEVPHASHALGORITHM_H
+
+#include "config.h"
+#include "HashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLEVPHashAlgorithm : public HashAlgorithm
+{
+public:
+ // Base constructors
+ OSSLEVPHashAlgorithm() : HashAlgorithm() {
+ curCTX = NULL;
+ }
+
+ // Destructor
+ ~OSSLEVPHashAlgorithm();
+
+ // Hashing functions
+ virtual bool hashInit();
+ virtual bool hashUpdate(const ByteString& data);
+ virtual bool hashFinal(ByteString& hashedData);
+
+ virtual int getHashSize() = 0;
+protected:
+ virtual const EVP_MD* getEVPHash() const = 0;
+
+private:
+ // Current hashing context
+ EVP_MD_CTX* curCTX;
+};
+
+#endif // !_SOFTHSM_V2_OSSLEVPHASHALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.cpp
new file mode 100644
index 0000000..960b341
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// TODO: Store context in securely allocated memory
+
+/*****************************************************************************
+ OSSLEVPMacAlgorithm.cpp
+
+ OpenSSL MAC algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLEVPMacAlgorithm.h"
+#include "OSSLComp.h"
+
+// Destructor
+OSSLEVPMacAlgorithm::~OSSLEVPMacAlgorithm()
+{
+ HMAC_CTX_free(curCTX);
+}
+
+// Signing functions
+bool OSSLEVPMacAlgorithm::signInit(const SymmetricKey* key)
+{
+ // Call the superclass initialiser
+ if (!MacAlgorithm::signInit(key))
+ {
+ return false;
+ }
+
+ // Initialize the context
+ curCTX = HMAC_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for HMAC_CTX");
+
+ return false;
+ }
+
+ // Initialize EVP signing
+ if (!HMAC_Init_ex(curCTX, key->getKeyBits().const_byte_str(), key->getKeyBits().size(), getEVPHash(), NULL))
+ {
+ ERROR_MSG("HMAC_Init failed");
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPMacAlgorithm::signUpdate(const ByteString& dataToSign)
+{
+ if (!MacAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ // The GOST implementation in OpenSSL will segfault if we update with zero length.
+ if (dataToSign.size() == 0) return true;
+
+ if (!HMAC_Update(curCTX, dataToSign.const_byte_str(), dataToSign.size()))
+ {
+ ERROR_MSG("HMAC_Update failed");
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPMacAlgorithm::signFinal(ByteString& signature)
+{
+ if (!MacAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ signature.resize(EVP_MD_size(getEVPHash()));
+ unsigned int outLen = signature.size();
+
+ if (!HMAC_Final(curCTX, &signature[0], &outLen))
+ {
+ ERROR_MSG("HMAC_Final failed");
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ signature.resize(outLen);
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool OSSLEVPMacAlgorithm::verifyInit(const SymmetricKey* key)
+{
+ // Call the superclass initialiser
+ if (!MacAlgorithm::verifyInit(key))
+ {
+ return false;
+ }
+
+ // Initialize the context
+ curCTX = HMAC_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for HMAC_CTX");
+
+ return false;
+ }
+
+ // Initialize EVP signing
+ if (!HMAC_Init_ex(curCTX, key->getKeyBits().const_byte_str(), key->getKeyBits().size(), getEVPHash(), NULL))
+ {
+ ERROR_MSG("HMAC_Init failed");
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPMacAlgorithm::verifyUpdate(const ByteString& originalData)
+{
+ if (!MacAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ // The GOST implementation in OpenSSL will segfault if we update with zero length.
+ if (originalData.size() == 0) return true;
+
+ if (!HMAC_Update(curCTX, originalData.const_byte_str(), originalData.size()))
+ {
+ ERROR_MSG("HMAC_Update failed");
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ MacAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLEVPMacAlgorithm::verifyFinal(ByteString& signature)
+{
+ if (!MacAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ ByteString macResult;
+ unsigned int outLen = EVP_MD_size(getEVPHash());
+ macResult.resize(outLen);
+
+ if (!HMAC_Final(curCTX, &macResult[0], &outLen))
+ {
+ ERROR_MSG("HMAC_Final failed");
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ HMAC_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return macResult == signature;
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.h b/SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.h
new file mode 100644
index 0000000..69e3f18
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPMacAlgorithm.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLEVPMacAlgorithm.h
+
+ OpenSSL MAC algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLEVPMACALGORITHM_H
+#define _SOFTHSM_V2_OSSLEVPMACALGORITHM_H
+
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "MacAlgorithm.h"
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+
+class OSSLEVPMacAlgorithm : public MacAlgorithm
+{
+public:
+ // Constructor
+ OSSLEVPMacAlgorithm() {
+ curCTX = NULL;
+ };
+
+ // Destructor
+ ~OSSLEVPMacAlgorithm();
+
+ // Signing functions
+ virtual bool signInit(const SymmetricKey* key);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verifyInit(const SymmetricKey* key);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(ByteString& signature);
+
+ // Return the MAC size
+ virtual size_t getMacSize() const = 0;
+
+protected:
+ // Return the right hash for the operation
+ virtual const EVP_MD* getEVPHash() const = 0;
+
+private:
+ // The current context
+ HMAC_CTX* curCTX;
+};
+
+#endif // !_SOFTHSM_V2_OSSLEVPMACALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.cpp
new file mode 100644
index 0000000..d43e741
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.cpp
@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// TODO: Store EVP context in securely allocated memory
+
+/*****************************************************************************
+ OSSLEVPSymmetricAlgorithm.cpp
+
+ OpenSSL symmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLEVPSymmetricAlgorithm.h"
+#include "OSSLUtil.h"
+#include "salloc.h"
+#include <openssl/err.h>
+
+// Constructor
+OSSLEVPSymmetricAlgorithm::OSSLEVPSymmetricAlgorithm()
+{
+ pCurCTX = NULL;
+ maximumBytes = BN_new();
+ BN_one(maximumBytes);
+ BN_set_negative(maximumBytes, 1);
+ counterBytes = BN_new();
+ BN_zero(counterBytes);
+}
+
+// Destructor
+OSSLEVPSymmetricAlgorithm::~OSSLEVPSymmetricAlgorithm()
+{
+ EVP_CIPHER_CTX_free(pCurCTX);
+ BN_free(maximumBytes);
+ BN_free(counterBytes);
+}
+
+// Encryption functions
+bool OSSLEVPSymmetricAlgorithm::encryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& IV /* = ByteString()*/, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& aad /* = ByteString() */, size_t tagBytes /* = 0 */)
+{
+ // Call the superclass initialiser
+ if (!SymmetricAlgorithm::encryptInit(key, mode, IV, padding, counterBits, aad, tagBytes))
+ {
+ return false;
+ }
+
+ // Check the IV
+ if (mode != SymMode::GCM && (IV.size() > 0) && (IV.size() != getBlockSize()))
+ {
+ ERROR_MSG("Invalid IV size (%d bytes, expected %d bytes)", IV.size(), getBlockSize());
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ ByteString iv;
+
+ if (IV.size() > 0)
+ {
+ iv = IV;
+ }
+ else
+ {
+ iv.wipe(getBlockSize());
+ }
+
+ // Check the counter bits
+ if (counterBits > 0)
+ {
+ BIGNUM* counter = OSSL::byteString2bn(iv);
+ BN_mask_bits(counter, counterBits);
+
+ // Reverse the bits
+ while (counterBits > 0)
+ {
+ counterBits--;
+ if (BN_is_bit_set(counter, counterBits))
+ {
+ BN_clear_bit(counter, counterBits);
+ }
+ else
+ {
+ BN_set_bit(counter, counterBits);
+ }
+ }
+
+ // Set the maximum bytes
+ BN_add_word(counter, 1);
+ BN_mul_word(counter, getBlockSize());
+ BN_copy(maximumBytes, counter);
+ BN_free(counter);
+ BN_zero(counterBytes);
+ }
+ else
+ {
+ BN_one(maximumBytes);
+ BN_set_negative(maximumBytes, 1);
+ }
+
+ // Determine the cipher class
+ const EVP_CIPHER* cipher = getCipher();
+
+ if (cipher == NULL)
+ {
+ ERROR_MSG("Failed to initialise EVP encrypt operation");
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ // Allocate the EVP context
+ pCurCTX = EVP_CIPHER_CTX_new();
+
+ if (pCurCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for EVP_CIPHER_CTX");
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ int rv;
+ if (mode == SymMode::GCM)
+ {
+ rv = EVP_EncryptInit_ex(pCurCTX, cipher, NULL, NULL, NULL);
+
+ if (rv)
+ {
+ EVP_CIPHER_CTX_ctrl(pCurCTX, EVP_CTRL_GCM_SET_IVLEN, iv.size(), NULL);
+ rv = EVP_EncryptInit_ex(pCurCTX, NULL, NULL, (unsigned char*) currentKey->getKeyBits().const_byte_str(), iv.byte_str());
+ }
+ }
+ else
+ {
+ rv = EVP_EncryptInit(pCurCTX, cipher, (unsigned char*) currentKey->getKeyBits().const_byte_str(), iv.byte_str());
+ }
+
+ if (!rv)
+ {
+ ERROR_MSG("Failed to initialise EVP encrypt operation: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ EVP_CIPHER_CTX_set_padding(pCurCTX, padding ? 1 : 0);
+
+ if (mode == SymMode::GCM)
+ {
+ int outLen = 0;
+ if (aad.size() && !EVP_EncryptUpdate(pCurCTX, NULL, &outLen, (unsigned char*) aad.const_byte_str(), aad.size()))
+ {
+ ERROR_MSG("Failed to update with AAD: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool OSSLEVPSymmetricAlgorithm::encryptUpdate(const ByteString& data, ByteString& encryptedData)
+{
+ if (!SymmetricAlgorithm::encryptUpdate(data, encryptedData))
+ {
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ if (data.size() == 0)
+ {
+ encryptedData.resize(0);
+
+ return true;
+ }
+
+ // Count number of bytes written
+ if (!BN_is_negative(maximumBytes))
+ {
+ BN_add_word(counterBytes, data.size());
+ }
+
+ // Prepare the output block
+ encryptedData.resize(data.size() + getBlockSize() - 1);
+
+ int outLen = encryptedData.size();
+ if (!EVP_EncryptUpdate(pCurCTX, &encryptedData[0], &outLen, (unsigned char*) data.const_byte_str(), data.size()))
+ {
+ ERROR_MSG("EVP_EncryptUpdate failed: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ ByteString dummy;
+ SymmetricAlgorithm::encryptFinal(dummy);
+
+ return false;
+ }
+
+ // Resize the output block
+ encryptedData.resize(outLen);
+ currentBufferSize -= outLen;
+
+ return true;
+}
+
+bool OSSLEVPSymmetricAlgorithm::encryptFinal(ByteString& encryptedData)
+{
+ SymMode::Type mode = currentCipherMode;
+ size_t tagBytes = currentTagBytes;
+
+ if (!SymmetricAlgorithm::encryptFinal(encryptedData))
+ {
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ // Prepare the output block
+ encryptedData.resize(getBlockSize());
+
+ int outLen = encryptedData.size();
+
+ if (!EVP_EncryptFinal(pCurCTX, &encryptedData[0], &outLen))
+ {
+ ERROR_MSG("EVP_EncryptFinal failed: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ // Resize the output block
+ encryptedData.resize(outLen);
+
+ if (mode == SymMode::GCM)
+ {
+ ByteString tag;
+ tag.resize(tagBytes);
+ EVP_CIPHER_CTX_ctrl(pCurCTX, EVP_CTRL_GCM_GET_TAG, tagBytes, &tag[0]);
+ encryptedData += tag;
+ }
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return true;
+}
+
+// Decryption functions
+bool OSSLEVPSymmetricAlgorithm::decryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& IV /* = ByteString() */, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& aad /* = ByteString() */, size_t tagBytes /* = 0 */)
+{
+ // Call the superclass initialiser
+ if (!SymmetricAlgorithm::decryptInit(key, mode, IV, padding, counterBits, aad, tagBytes))
+ {
+ return false;
+ }
+
+ // Check the IV
+ if (mode != SymMode::GCM && (IV.size() > 0) && (IV.size() != getBlockSize()))
+ {
+ ERROR_MSG("Invalid IV size (%d bytes, expected %d bytes)", IV.size(), getBlockSize());
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ ByteString iv;
+
+ if (IV.size() > 0)
+ {
+ iv = IV;
+ }
+ else
+ {
+ iv.wipe(getBlockSize());
+ }
+
+ // Check the counter bits
+ if (counterBits > 0)
+ {
+ BIGNUM* counter = OSSL::byteString2bn(iv);
+ BN_mask_bits(counter, counterBits);
+
+ // Reverse the bits
+ while (counterBits > 0)
+ {
+ counterBits--;
+ if (BN_is_bit_set(counter, counterBits))
+ {
+ BN_clear_bit(counter, counterBits);
+ }
+ else
+ {
+ BN_set_bit(counter, counterBits);
+ }
+ }
+
+ // Set the maximum bytes
+ BN_add_word(counter, 1);
+ BN_mul_word(counter, getBlockSize());
+ BN_copy(maximumBytes, counter);
+ BN_free(counter);
+ BN_zero(counterBytes);
+ }
+ else
+ {
+ BN_one(maximumBytes);
+ BN_set_negative(maximumBytes, 1);
+ }
+
+ // Determine the cipher class
+ const EVP_CIPHER* cipher = getCipher();
+
+ if (cipher == NULL)
+ {
+ ERROR_MSG("Failed to initialise EVP decrypt operation");
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ // Allocate the EVP context
+ pCurCTX = EVP_CIPHER_CTX_new();
+
+ if (pCurCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for EVP_CIPHER_CTX");
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ int rv;
+ if (mode == SymMode::GCM)
+ {
+ rv = EVP_DecryptInit_ex(pCurCTX, cipher, NULL, NULL, NULL);
+
+ if (rv)
+ {
+ EVP_CIPHER_CTX_ctrl(pCurCTX, EVP_CTRL_GCM_SET_IVLEN, iv.size(), NULL);
+ rv = EVP_DecryptInit_ex(pCurCTX, NULL, NULL, (unsigned char*) currentKey->getKeyBits().const_byte_str(), iv.byte_str());
+ }
+ }
+ else
+ {
+ rv = EVP_DecryptInit(pCurCTX, cipher, (unsigned char*) currentKey->getKeyBits().const_byte_str(), iv.byte_str());
+ }
+
+ if (!rv)
+ {
+ ERROR_MSG("Failed to initialise EVP decrypt operation: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ EVP_CIPHER_CTX_set_padding(pCurCTX, padding ? 1 : 0);
+
+ if (mode == SymMode::GCM)
+ {
+ int outLen = 0;
+ if (aad.size() && !EVP_DecryptUpdate(pCurCTX, NULL, &outLen, (unsigned char*) aad.const_byte_str(), aad.size()))
+ {
+ ERROR_MSG("Failed to update with AAD: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool OSSLEVPSymmetricAlgorithm::decryptUpdate(const ByteString& encryptedData, ByteString& data)
+{
+ if (!SymmetricAlgorithm::decryptUpdate(encryptedData, data))
+ {
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ // AEAD ciphers should not return decrypted data until final is called
+ if (currentCipherMode == SymMode::GCM)
+ {
+ data.resize(0);
+ return true;
+ }
+
+ // Count number of bytes written
+ if (!BN_is_negative(maximumBytes))
+ {
+ BN_add_word(counterBytes, encryptedData.size());
+ }
+
+ // Prepare the output block
+ data.resize(encryptedData.size() + getBlockSize());
+
+ int outLen = data.size();
+
+ DEBUG_MSG("Decrypting %d bytes into buffer of %d bytes", encryptedData.size(), data.size());
+
+ if (!EVP_DecryptUpdate(pCurCTX, &data[0], &outLen, (unsigned char*) encryptedData.const_byte_str(), encryptedData.size()))
+ {
+ ERROR_MSG("EVP_DecryptUpdate failed: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ ByteString dummy;
+ SymmetricAlgorithm::decryptFinal(dummy);
+
+ return false;
+ }
+
+ DEBUG_MSG("Decrypt returned %d bytes of data", outLen);
+
+ // Resize the output block
+ data.resize(outLen);
+ currentBufferSize -= outLen;
+
+ return true;
+}
+
+bool OSSLEVPSymmetricAlgorithm::decryptFinal(ByteString& data)
+{
+ SymMode::Type mode = currentCipherMode;
+ size_t tagBytes = currentTagBytes;
+ ByteString aeadBuffer = currentAEADBuffer;
+
+ if (!SymmetricAlgorithm::decryptFinal(data))
+ {
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ data.resize(0);
+ if (mode == SymMode::GCM)
+ {
+ // Check buffer size
+ if (aeadBuffer.size() < tagBytes)
+ {
+ ERROR_MSG("Tag bytes (%d) does not fit in AEAD buffer (%d)", tagBytes, aeadBuffer.size());
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ // Set the tag
+ EVP_CIPHER_CTX_ctrl(pCurCTX, EVP_CTRL_GCM_SET_TAG, tagBytes, &aeadBuffer[aeadBuffer.size()-tagBytes]);
+
+ // Prepare the output block
+ data.resize(aeadBuffer.size() - tagBytes + getBlockSize());
+ int outLen = data.size();
+
+ if (!EVP_DecryptUpdate(pCurCTX, &data[0], &outLen, (unsigned char*) aeadBuffer.const_byte_str(), aeadBuffer.size() - tagBytes))
+ {
+ ERROR_MSG("EVP_DecryptUpdate failed: %s", ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ data.resize(outLen);
+ }
+
+ // Prepare the output block
+ int initialSize = data.size();
+ data.resize(initialSize + getBlockSize());
+
+ int outLen = data.size() - initialSize;
+ int rv;
+
+ if (!(rv = EVP_DecryptFinal(pCurCTX, &data[initialSize], &outLen)))
+ {
+ ERROR_MSG("EVP_DecryptFinal failed (0x%08X): %s", rv, ERR_error_string(ERR_get_error(), NULL));
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return false;
+ }
+
+ // Resize the output block
+ data.resize(initialSize + outLen);
+
+ EVP_CIPHER_CTX_free(pCurCTX);
+ pCurCTX = NULL;
+
+ return true;
+}
+
+// Check if more bytes of data can be encrypted
+bool OSSLEVPSymmetricAlgorithm::checkMaximumBytes(unsigned long bytes)
+{
+ if (BN_is_negative(maximumBytes)) return true;
+
+ BIGNUM* bigNum = BN_new();
+ BN_copy(bigNum, counterBytes);
+ BN_add_word(bigNum, bytes);
+
+ bool rv = false;
+ if (BN_cmp(maximumBytes, bigNum) >= 0) rv = true;
+
+ BN_free(bigNum);
+
+ return rv;
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.h b/SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.h
new file mode 100644
index 0000000..66bbeef
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLEVPSymmetricAlgorithm.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLEVPSymmetricAlgorithm.h
+
+ OpenSSL symmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLEVPSYMMETRICALGORITHM_H
+#define _SOFTHSM_V2_OSSLEVPSYMMETRICALGORITHM_H
+
+#include <openssl/evp.h>
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "SymmetricAlgorithm.h"
+
+class OSSLEVPSymmetricAlgorithm : public SymmetricAlgorithm
+{
+public:
+ // Constructor
+ OSSLEVPSymmetricAlgorithm();
+
+ // Destructor
+ virtual ~OSSLEVPSymmetricAlgorithm();
+
+ // Encryption functions
+ virtual bool encryptInit(const SymmetricKey* key, const SymMode::Type mode = SymMode::CBC, const ByteString& IV = ByteString(), bool padding = true, size_t counterBits = 0, const ByteString& aad = ByteString(), size_t tagBytes = 0);
+ virtual bool encryptUpdate(const ByteString& data, ByteString& encryptedData);
+ virtual bool encryptFinal(ByteString& encryptedData);
+
+ // Decryption functions
+ virtual bool decryptInit(const SymmetricKey* key, const SymMode::Type mode = SymMode::CBC, const ByteString& IV = ByteString(), bool padding = true, size_t counterBits = 0, const ByteString& aad = ByteString(), size_t tagBytes = 0);
+ virtual bool decryptUpdate(const ByteString& encryptedData, ByteString& data);
+ virtual bool decryptFinal(ByteString& data);
+
+ // Return the block size
+ virtual size_t getBlockSize() const = 0;
+
+ // Check if more bytes of data can be encrypted
+ virtual bool checkMaximumBytes(unsigned long bytes);
+
+protected:
+ // Return the right EVP cipher for the operation
+ virtual const EVP_CIPHER* getCipher() const = 0;
+
+private:
+ // The current EVP context
+ EVP_CIPHER_CTX* pCurCTX;
+
+ // The maximum bytes to encrypt/decrypt
+ BIGNUM* maximumBytes;
+ BIGNUM* counterBytes;
+};
+
+#endif // !_SOFTHSM_V2_OSSLEVPSYMMETRICALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOST.cpp b/SoftHSMv2/src/lib/crypto/OSSLGOST.cpp
new file mode 100644
index 0000000..4f34d45
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOST.cpp
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOST.cpp
+
+ OpenSSL GOST R 34.10-2001 asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "OSSLGOST.h"
+#include "OSSLCryptoFactory.h"
+#include "ECParameters.h"
+#include "OSSLGOSTKeyPair.h"
+#include "OSSLGOSTPrivateKey.h"
+#include "OSSLGOSTPublicKey.h"
+#include "OSSLComp.h"
+#include <algorithm>
+#include <openssl/ecdsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <string.h>
+
+// Destructor
+OSSLGOST::~OSSLGOST()
+{
+ EVP_MD_CTX_free(curCTX);
+}
+
+// Signing functions
+bool OSSLGOST::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (mechanism == AsymMech::GOST)
+ {
+ // Separate implementation for GOST signing without hash computation
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLGOSTPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // In case of raw GOST, the length of the input data must be 32 bytes
+ if (dataToSign.size() != 32)
+ {
+ ERROR_MSG("Size of data to sign is not 32 bytes");
+
+ return false;
+ }
+
+ // Perform the signature operation
+ OSSLGOSTPrivateKey* osslKey = (OSSLGOSTPrivateKey*) privateKey;
+ EVP_PKEY* pkey = osslKey->getOSSLKey();
+ size_t outLen;
+
+ if (pkey == NULL)
+ {
+ ERROR_MSG("Could not get the OpenSSL private key");
+
+ return false;
+ }
+
+ signature.resize(EVP_PKEY_size(pkey));
+ outLen = signature.size();
+
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,NULL);
+ if (ctx == NULL)
+ {
+ ERROR_MSG("EVP_PKEY_CTX_new failed");
+ return false;
+ }
+
+ if (EVP_PKEY_sign_init(ctx) <= 0)
+ {
+ ERROR_MSG("EVP_PKEY_sign_init failed");
+ EVP_PKEY_CTX_free(ctx);
+ return false;
+ }
+
+ if (EVP_PKEY_sign(ctx, &signature[0], &outLen, dataToSign.const_byte_str(), dataToSign.size()) <= 0)
+ {
+ ERROR_MSG("An error occurred while performing a signature");
+ EVP_PKEY_CTX_free(ctx);
+ return false;
+ }
+
+ signature.resize(outLen);
+ EVP_PKEY_CTX_free(ctx);
+
+ return true;
+ }
+ else
+ {
+ // Call default implementation
+ return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
+ }
+}
+
+bool OSSLGOST::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLGOSTPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ if (mechanism != AsymMech::GOST_GOST)
+ {
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ curCTX = EVP_MD_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for EVP_MD_CTX");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ const EVP_MD* md = OSSLCryptoFactory::i()->EVP_GOST_34_11;
+ if (!EVP_DigestInit_ex(curCTX, md, NULL))
+ {
+ ERROR_MSG("EVP_DigestInit_ex failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLGOST::signUpdate(const ByteString& dataToSign)
+{
+ if (!AsymmetricAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ if (!EVP_DigestUpdate(curCTX, dataToSign.const_byte_str(), dataToSign.size()))
+ {
+ ERROR_MSG("EVP_DigestUpdate failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLGOST::signFinal(ByteString& signature)
+{
+ // Save necessary state before calling super class signFinal
+ OSSLGOSTPrivateKey* pk = (OSSLGOSTPrivateKey*) currentPrivateKey;
+
+ if (!AsymmetricAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the signature operation
+ EVP_PKEY* pkey = pk->getOSSLKey();
+ unsigned int outLen;
+
+ if (pkey == NULL)
+ {
+ ERROR_MSG("Could not get the OpenSSL private key");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ signature.resize(EVP_PKEY_size(pkey));
+ outLen = signature.size();
+ if (!EVP_SignFinal(curCTX, &signature[0], &outLen, pkey))
+ {
+ ERROR_MSG("EVP_SignFinal failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ signature.resize(outLen);
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return true;
+}
+
+// Verification functions
+bool OSSLGOST::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (mechanism == AsymMech::GOST)
+ {
+ // Separate implementation for GOST verification without hash computation
+
+ // Check if the private key is the right type
+ if (!publicKey->isOfType(OSSLGOSTPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Perform the verification operation
+ OSSLGOSTPublicKey* osslKey = (OSSLGOSTPublicKey*) publicKey;
+ EVP_PKEY* pkey = osslKey->getOSSLKey();
+
+ if (pkey == NULL)
+ {
+ ERROR_MSG("Could not get the OpenSSL public key");
+
+ return false;
+ }
+
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey,NULL);
+ if (ctx == NULL)
+ {
+ ERROR_MSG("EVP_PKEY_CTX_new failed");
+ return false;
+ }
+
+ if (EVP_PKEY_verify_init(ctx) <= 0)
+ {
+ ERROR_MSG("EVP_PKEY_verify_init failed");
+ EVP_PKEY_CTX_free(ctx);
+ return false;
+ }
+
+ int ret = EVP_PKEY_verify(ctx, signature.const_byte_str(), signature.size(), originalData.const_byte_str(), originalData.size());
+ EVP_PKEY_CTX_free(ctx);
+ if (ret != 1)
+ {
+ if (ret < 0)
+ ERROR_MSG("GOST verify failed (0x%08X)", ERR_get_error());
+
+ return false;
+ }
+ return true;
+ }
+ else
+ {
+ // Call the generic function
+ return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
+ }
+}
+
+bool OSSLGOST::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(OSSLGOSTPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ if (mechanism != AsymMech::GOST_GOST)
+ {
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ curCTX = EVP_MD_CTX_new();
+ if (curCTX == NULL)
+ {
+ ERROR_MSG("Failed to allocate space for EVP_MD_CTX");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ const EVP_MD* md = OSSLCryptoFactory::i()->EVP_GOST_34_11;
+ if (!EVP_DigestInit_ex(curCTX, md, NULL))
+ {
+ ERROR_MSG("EVP_DigestInit_ex failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLGOST::verifyUpdate(const ByteString& originalData)
+{
+ if (!AsymmetricAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ if (!EVP_DigestUpdate(curCTX, originalData.const_byte_str(), originalData.size()))
+ {
+ ERROR_MSG("EVP_DigestUpdate failed");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLGOST::verifyFinal(const ByteString& signature)
+{
+ // Save necessary state before calling super class verifyFinal
+ OSSLGOSTPublicKey* pk = (OSSLGOSTPublicKey*) currentPublicKey;
+
+ if (!AsymmetricAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ // Perform the verify operation
+ EVP_PKEY *pkey = pk->getOSSLKey();
+ int ret;
+
+ if (pkey == NULL)
+ {
+ ERROR_MSG("Could not get the OpenSSL public key");
+
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+
+ return false;
+ }
+
+ ret = EVP_VerifyFinal(curCTX, signature.const_byte_str(), signature.size(), pkey);
+ EVP_MD_CTX_free(curCTX);
+ curCTX = NULL;
+ if (ret != 1)
+ {
+ if (ret < 0)
+ ERROR_MSG("GOST verify failed (0x%08X)", ERR_get_error());
+
+ return false;
+ }
+ return true;
+}
+
+// Encryption functions
+bool OSSLGOST::encrypt(PublicKey* /*publicKey*/, const ByteString& /*data*/,
+ ByteString& /*encryptedData*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("GOST does not support encryption");
+
+ return false;
+}
+
+// Decryption functions
+bool OSSLGOST::decrypt(PrivateKey* /*privateKey*/, const ByteString& /*encryptedData*/,
+ ByteString& /*data*/, const AsymMech::Type /*padding*/)
+{
+ ERROR_MSG("GOST does not support decryption");
+
+ return false;
+}
+
+// Key factory
+bool OSSLGOST::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(ECParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for GOST key generation");
+
+ return false;
+ }
+
+ ECParameters* params = (ECParameters*) parameters;
+ ByteString paramA = "06072a850302022301";
+ if (params->getEC() != paramA)
+ {
+ ERROR_MSG("unsupported parameters");
+
+ return false;
+ }
+
+ // Generate the key-pair
+ EVP_PKEY_CTX* ctx = NULL;
+ EVP_PKEY* pkey = NULL;
+ OSSLGOSTKeyPair* kp;
+
+ ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL);
+ if (ctx == NULL)
+ {
+ ERROR_MSG("EVP_PKEY_CTX_new_id failed");
+
+ goto err;
+ }
+ if (EVP_PKEY_keygen_init(ctx) <= 0)
+ {
+ ERROR_MSG("EVP_PKEY_keygen_init failed");
+
+ goto err;
+ }
+ if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0)
+ {
+ ERROR_MSG("EVP_PKEY_CTX_ctrl_str failed");
+
+ goto err;
+ }
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+ {
+ ERROR_MSG("EVP_PKEY_keygen failed");
+
+ goto err;
+ }
+ EVP_PKEY_CTX_free(ctx);
+ ctx = NULL;
+
+ // Create an asymmetric key-pair object to return
+ kp = new OSSLGOSTKeyPair();
+
+ ((OSSLGOSTPublicKey*) kp->getPublicKey())->setFromOSSL(pkey);
+ ((OSSLGOSTPrivateKey*) kp->getPrivateKey())->setFromOSSL(pkey);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ EVP_PKEY_free(pkey);
+
+ return true;
+
+err:
+ if (ctx != NULL)
+ EVP_PKEY_CTX_free(ctx);
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+
+ return false;
+}
+
+unsigned long OSSLGOST::getMinKeySize()
+{
+ return 0;
+}
+
+unsigned long OSSLGOST::getMaxKeySize()
+{
+ return 0;
+}
+
+bool OSSLGOST::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ OSSLGOSTKeyPair* kp = new OSSLGOSTKeyPair();
+
+ bool rv = true;
+
+ if (!((OSSLGOSTPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((OSSLGOSTPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool OSSLGOST::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLGOSTPublicKey* pub = new OSSLGOSTPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool OSSLGOST::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLGOSTPrivateKey* priv = new OSSLGOSTPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* OSSLGOST::newPublicKey()
+{
+ return (PublicKey*) new OSSLGOSTPublicKey();
+}
+
+PrivateKey* OSSLGOST::newPrivateKey()
+{
+ return (PrivateKey*) new OSSLGOSTPrivateKey();
+}
+
+AsymmetricParameters* OSSLGOST::newParameters()
+{
+ return (AsymmetricParameters*) new ECParameters();
+}
+
+bool OSSLGOST::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ECParameters* params = new ECParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOST.h b/SoftHSMv2/src/lib/crypto/OSSLGOST.h
new file mode 100644
index 0000000..ad399f1
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOST.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOST.h
+
+ OpenSSL GOST R 34.10-2001 asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLGOST_H
+#define _SOFTHSM_V2_OSSLGOST_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLGOST : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ OSSLGOST() : AsymmetricAlgorithm() {
+ curCTX = NULL;
+ }
+
+ // Destructor
+ ~OSSLGOST();
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ EVP_MD_CTX* curCTX;
+};
+
+#endif // !_SOFTHSM_V2_OSSLGOST_H
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.cpp b/SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.cpp
new file mode 100644
index 0000000..969a216
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTKeyPair.cpp
+
+ OpenSSL GOST R 34.10-2001 key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "OSSLGOSTKeyPair.h"
+
+// Set the public key
+void OSSLGOSTKeyPair::setPublicKey(OSSLGOSTPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void OSSLGOSTKeyPair::setPrivateKey(OSSLGOSTPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* OSSLGOSTKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* OSSLGOSTKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* OSSLGOSTKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* OSSLGOSTKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.h b/SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.h
new file mode 100644
index 0000000..b064704
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTKeyPair.h
+
+ OpenSSL GOST R 34.10-2001 key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLGOSTKEYPAIR_H
+#define _SOFTHSM_V2_OSSLGOSTKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "OSSLGOSTPublicKey.h"
+#include "OSSLGOSTPrivateKey.h"
+
+class OSSLGOSTKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(OSSLGOSTPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(OSSLGOSTPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ OSSLGOSTPublicKey pubKey;
+
+ // The private key
+ OSSLGOSTPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLGOSTKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.cpp
new file mode 100644
index 0000000..6371e8f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTPrivateKey.cpp
+
+ OpenSSL GOST R 34.10-2001 private key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "OSSLGOSTPrivateKey.h"
+#include "OSSLUtil.h"
+#include <string.h>
+#include <openssl/ec.h>
+
+// DER of a private key
+const unsigned char dummyKey[] = {
+ 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
+ 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
+ 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
+ 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
+ 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b,
+ 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5,
+ 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65,
+ 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63,
+ 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6
+};
+
+// Constructors
+OSSLGOSTPrivateKey::OSSLGOSTPrivateKey()
+{
+ pkey = EVP_PKEY_new();
+}
+
+OSSLGOSTPrivateKey::OSSLGOSTPrivateKey(const EVP_PKEY* inPKEY)
+{
+ OSSLGOSTPrivateKey();
+
+ setFromOSSL(inPKEY);
+}
+
+// Destructor
+OSSLGOSTPrivateKey::~OSSLGOSTPrivateKey()
+{
+ EVP_PKEY_free(pkey);
+}
+
+// The type
+/*static*/ const char* OSSLGOSTPrivateKey::type = "OpenSSL GOST Private Key";
+
+// Get the output length
+unsigned long OSSLGOSTPrivateKey::getOutputLength() const
+{
+ return 64;
+}
+
+// Set from OpenSSL representation
+void OSSLGOSTPrivateKey::setFromOSSL(const EVP_PKEY* pkey)
+{
+ const EC_KEY* eckey = (const EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
+ const BIGNUM* priv = EC_KEY_get0_private_key(eckey);
+ setD(OSSL::bn2ByteString(priv));
+
+ ByteString inEC;
+ int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+ inEC.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL));
+ unsigned char *p = &inEC[0];
+ i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p);
+ setEC(inEC);
+}
+
+// Check if the key is of the given type
+bool OSSLGOSTPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the GOST private key components
+void OSSLGOSTPrivateKey::setD(const ByteString& inD)
+{
+ GOSTPrivateKey::setD(inD);
+
+ EC_KEY* inEC = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
+ if (inEC == NULL)
+ {
+ const unsigned char* p = dummyKey;
+ if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, (long) sizeof(dummyKey)) == NULL)
+ {
+ ERROR_MSG("d2i_PrivateKey failed");
+
+ return;
+ }
+ inEC = (EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
+ }
+
+ const BIGNUM* priv = OSSL::byteString2bn(inD);
+ if (EC_KEY_set_private_key(inEC, priv) <= 0)
+ {
+ ERROR_MSG("EC_KEY_set_private_key failed");
+ return;
+ }
+ BN_clear_free((BIGNUM*)priv);
+
+#ifdef notyet
+ if (gost2001_compute_public(inEC) <= 0)
+ ERROR_MSG("gost2001_compute_public failed");
+#endif
+}
+
+// Setters for the GOST public key components
+void OSSLGOSTPrivateKey::setEC(const ByteString& inEC)
+{
+ GOSTPrivateKey::setEC(inEC);
+}
+
+// Retrieve the OpenSSL representation of the key
+EVP_PKEY* OSSLGOSTPrivateKey::getOSSLKey()
+{
+ return pkey;
+}
+
+// Serialisation
+ByteString OSSLGOSTPrivateKey::serialise() const
+{
+ return ec.serialise() +
+ d.serialise();
+}
+
+bool OSSLGOSTPrivateKey::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+ ByteString dD = ByteString::chainDeserialise(serialised);
+
+ if ((dEC.size() == 0) ||
+ (dD.size() == 0))
+ {
+ return false;
+ }
+
+ setEC(dEC);
+ setD(dD);
+
+ return true;
+}
+
+// Encode into PKCS#8 DER
+ByteString OSSLGOSTPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ // TODO
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool OSSLGOSTPrivateKey::PKCS8Decode(const ByteString& /*ber*/)
+{
+ return false;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.h b/SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.h
new file mode 100644
index 0000000..eca0f13
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTPrivateKey.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTPrivateKey.h
+
+ OpenSSL GOST R 34.10-2001 private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLGOSTPRIVATEKEY_H
+#define _SOFTHSM_V2_OSSLGOSTPRIVATEKEY_H
+
+#include "config.h"
+#include "GOSTPrivateKey.h"
+#include <openssl/evp.h>
+
+class OSSLGOSTPrivateKey : public GOSTPrivateKey
+{
+public:
+ // Constructors
+ OSSLGOSTPrivateKey();
+
+ OSSLGOSTPrivateKey(const EVP_PKEY* inPKEY);
+
+ // Destructor
+ virtual ~OSSLGOSTPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the GOST private key components
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the GOST public key components
+ virtual void setEC(const ByteString& inEC);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const EVP_PKEY* pkey);
+
+ // Retrieve the OpenSSL representation of the key
+ EVP_PKEY* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ EVP_PKEY* pkey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLGOSTPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.cpp
new file mode 100644
index 0000000..5810637
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTPublicKey.cpp
+
+ OpenSSL GOST R 34.10-2001 public key class
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "log.h"
+#include "OSSLGOSTPublicKey.h"
+#include <openssl/x509.h>
+#include <string.h>
+
+// the 37 bytes of prefix
+const unsigned char gost_prefix[] = {
+ 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
+ 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07,
+ 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06,
+ 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01,
+ 0x03, 0x43, 0x00, 0x04, 0x40
+};
+
+// Constructors
+OSSLGOSTPublicKey::OSSLGOSTPublicKey()
+{
+ pkey = EVP_PKEY_new();
+}
+
+OSSLGOSTPublicKey::OSSLGOSTPublicKey(const EVP_PKEY* inPKEY)
+{
+ OSSLGOSTPublicKey();
+
+ setFromOSSL(inPKEY);
+}
+
+// Destructor
+OSSLGOSTPublicKey::~OSSLGOSTPublicKey()
+{
+ EVP_PKEY_free(pkey);
+}
+
+// The type
+/*static*/ const char* OSSLGOSTPublicKey::type = "OpenSSL GOST Public Key";
+
+// Get the output length
+unsigned long OSSLGOSTPublicKey::getOutputLength() const
+{
+ return getQ().size();
+}
+
+// Set from OpenSSL representation
+void OSSLGOSTPublicKey::setFromOSSL(const EVP_PKEY* pkey)
+{
+ ByteString der;
+ int len = i2d_PUBKEY((EVP_PKEY*) pkey, NULL);
+ if (len != 37 + 64)
+ {
+ ERROR_MSG("bad GOST public key encoding length %d", len);
+ return;
+ }
+ der.resize(len);
+ unsigned char *p = &der[0];
+ i2d_PUBKEY((EVP_PKEY*) pkey, &p);
+ // can check: der is prefix + 64 bytes
+ setQ(der.substr(37));
+
+ ByteString inEC;
+ const EC_KEY* eckey = (const EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
+ int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
+ inEC.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL));
+ p = &inEC[0];
+ i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p);
+ setEC(inEC);
+}
+
+// Check if the key is of the given type
+bool OSSLGOSTPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the GOST public key components
+void OSSLGOSTPublicKey::setEC(const ByteString& inEC)
+{
+ GOSTPublicKey::setEC(inEC);
+}
+
+void OSSLGOSTPublicKey::setQ(const ByteString& inQ)
+{
+ GOSTPublicKey::setQ(inQ);
+
+ if (inQ.size() != 64)
+ {
+ ERROR_MSG("bad GOST public key size %zu", q.size());
+ return;
+ }
+
+ ByteString der;
+ der.resize(37 + 64);
+ memcpy(&der[0], gost_prefix, 37);
+ memcpy(&der[37], inQ.const_byte_str(), 64);
+ const unsigned char *p = &der[0];
+ if (d2i_PUBKEY(&pkey, &p, (long) der.size()) == NULL)
+ ERROR_MSG("d2i_PUBKEY failed");
+}
+
+// Serialisation
+ByteString OSSLGOSTPublicKey::serialise() const
+{
+ return ec.serialise() +
+ q.serialise();
+}
+
+bool OSSLGOSTPublicKey::deserialise(ByteString& serialised)
+{
+ ByteString dEC = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+
+ if ((dEC.size() == 0) ||
+ (dQ.size() == 0))
+ {
+ return false;
+ }
+
+ setEC(dEC);
+ setQ(dQ);
+
+ return true;
+}
+
+// Retrieve the OpenSSL representation of the key
+EVP_PKEY* OSSLGOSTPublicKey::getOSSLKey()
+{
+ return pkey;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.h b/SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.h
new file mode 100644
index 0000000..c951962
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTPublicKey.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTPublicKey.h
+
+ OpenSSL GOST R 34.10-2001 public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLGOSTPUBLICKEY_H
+#define _SOFTHSM_V2_OSSLGOSTPUBLICKEY_H
+
+#include "config.h"
+#include "GOSTPublicKey.h"
+#include <openssl/evp.h>
+
+class OSSLGOSTPublicKey : public GOSTPublicKey
+{
+public:
+ // Constructors
+ OSSLGOSTPublicKey();
+
+ OSSLGOSTPublicKey(const EVP_PKEY* inPKEY);
+
+ // Destructor
+ virtual ~OSSLGOSTPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the GOST public key components
+ virtual void setEC(const ByteString& inEC);
+ virtual void setQ(const ByteString& inQ);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const EVP_PKEY* pkey);
+
+ // Retrieve the OpenSSL representation of the key
+ EVP_PKEY* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ EVP_PKEY* pkey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLDSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.cpp b/SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.cpp
new file mode 100644
index 0000000..5361075
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTR3411.h
+
+ OpenSSL GOST R 34.11-94 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#ifdef WITH_GOST
+#include "OSSLGOSTR3411.h"
+#include "OSSLCryptoFactory.h"
+#include <openssl/evp.h>
+
+int OSSLGOSTR3411::getHashSize()
+{
+ return 32;
+}
+
+const EVP_MD* OSSLGOSTR3411::getEVPHash() const
+{
+ return OSSLCryptoFactory::i()->EVP_GOST_34_11;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.h b/SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.h
new file mode 100644
index 0000000..8175258
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLGOSTR3411.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLGOSTR3411.h
+
+ OpenSSL GOST R 34.11-94 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLGOSTR3411_H
+#define _SOFTHSM_V2_OSSLGOSTR3411_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLGOSTR3411 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLGOSTR3411_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLHMAC.cpp b/SoftHSMv2/src/lib/crypto/OSSLHMAC.cpp
new file mode 100644
index 0000000..f8b73a7
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLHMAC.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLHMAC.cpp
+
+ OpenSSL HMAC implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLHMAC.h"
+#ifdef WITH_GOST
+#include "OSSLCryptoFactory.h"
+#endif
+
+const EVP_MD* OSSLHMACMD5::getEVPHash() const
+{
+ return EVP_md5();
+}
+
+size_t OSSLHMACMD5::getMacSize() const
+{
+ return 16;
+}
+
+const EVP_MD* OSSLHMACSHA1::getEVPHash() const
+{
+ return EVP_sha1();
+}
+
+size_t OSSLHMACSHA1::getMacSize() const
+{
+ return 20;
+}
+
+const EVP_MD* OSSLHMACSHA224::getEVPHash() const
+{
+ return EVP_sha224();
+}
+
+size_t OSSLHMACSHA224::getMacSize() const
+{
+ return 28;
+}
+
+const EVP_MD* OSSLHMACSHA256::getEVPHash() const
+{
+ return EVP_sha256();
+}
+
+size_t OSSLHMACSHA256::getMacSize() const
+{
+ return 32;
+}
+
+const EVP_MD* OSSLHMACSHA384::getEVPHash() const
+{
+ return EVP_sha384();
+}
+
+size_t OSSLHMACSHA384::getMacSize() const
+{
+ return 48;
+}
+
+const EVP_MD* OSSLHMACSHA512::getEVPHash() const
+{
+ return EVP_sha512();
+}
+
+size_t OSSLHMACSHA512::getMacSize() const
+{
+ return 64;
+}
+
+#ifdef WITH_GOST
+const EVP_MD* OSSLHMACGOSTR3411::getEVPHash() const
+{
+ return OSSLCryptoFactory::i()->EVP_GOST_34_11;
+}
+
+size_t OSSLHMACGOSTR3411::getMacSize() const
+{
+ return 32;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLHMAC.h b/SoftHSMv2/src/lib/crypto/OSSLHMAC.h
new file mode 100644
index 0000000..852614e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLHMAC.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLHMAC.h
+
+ OpenSSL HMAC implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLHMAC_H
+#define _SOFTHSM_V2_OSSLHMAC_H
+
+#include "config.h"
+#include "OSSLEVPMacAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLHMACMD5 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+
+class OSSLHMACSHA1 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+
+class OSSLHMACSHA224 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+
+class OSSLHMACSHA256 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+
+class OSSLHMACSHA384 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+
+class OSSLHMACSHA512 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+
+#ifdef WITH_GOST
+class OSSLHMACGOSTR3411 : public OSSLEVPMacAlgorithm
+{
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+ virtual size_t getMacSize() const;
+};
+#endif
+
+#endif // !_SOFTHSM_V2_OSSLHMAC_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLMD5.cpp b/SoftHSMv2/src/lib/crypto/OSSLMD5.cpp
new file mode 100644
index 0000000..2c962a6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLMD5.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLMD5.h
+
+ OpenSSL MD5 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLMD5.h"
+#include <openssl/evp.h>
+
+int OSSLMD5::getHashSize()
+{
+ return 16;
+}
+
+const EVP_MD* OSSLMD5::getEVPHash() const
+{
+ return EVP_md5();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLMD5.h b/SoftHSMv2/src/lib/crypto/OSSLMD5.h
new file mode 100644
index 0000000..22d7111
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLMD5.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLMD5.h
+
+ OpenSSL MD5 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLMD5_H
+#define _SOFTHSM_V2_OSSLMD5_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLMD5 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLMD5_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRNG.cpp b/SoftHSMv2/src/lib/crypto/OSSLRNG.cpp
new file mode 100644
index 0000000..d6a1e5d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRNG.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRNG.cpp
+
+ OpenSSL random number generator class
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLRNG.h"
+#include <openssl/rand.h>
+
+// Generate random data
+bool OSSLRNG::generateRandom(ByteString& data, const size_t len)
+{
+ data.wipe(len);
+
+ if (len == 0)
+ return true;
+ return RAND_bytes(&data[0], len) == 1;
+}
+
+// Seed the random pool
+void OSSLRNG::seed(ByteString& seedData)
+{
+ RAND_seed(seedData.byte_str(), seedData.size());
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRNG.h b/SoftHSMv2/src/lib/crypto/OSSLRNG.h
new file mode 100644
index 0000000..829f593
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRNG.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRNG.h
+
+ OpenSSL random number generator class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLRNG_H
+#define _SOFTHSM_V2_OSSLRNG_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "RNG.h"
+
+class OSSLRNG : public RNG
+{
+public:
+ // Generate random data
+ virtual bool generateRandom(ByteString& data, const size_t len);
+
+ // Seed the random pool
+ virtual void seed(ByteString& seedData);
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_OSSLRNG_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSA.cpp b/SoftHSMv2/src/lib/crypto/OSSLRSA.cpp
new file mode 100644
index 0000000..1e5638a
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSA.cpp
@@ -0,0 +1,1554 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSA.cpp
+
+ OpenSSL RSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLRSA.h"
+#include "OSSLUtil.h"
+#include "CryptoFactory.h"
+#include "RSAParameters.h"
+#include "OSSLRSAKeyPair.h"
+#include <algorithm>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+// Constructor
+OSSLRSA::OSSLRSA()
+{
+ pCurrentHash = NULL;
+ pSecondHash = NULL;
+ sLen = 0;
+}
+
+// Destructor
+OSSLRSA::~OSSLRSA()
+{
+ if (pCurrentHash != NULL)
+ {
+ delete pCurrentHash;
+ }
+
+ if (pSecondHash != NULL)
+ {
+ delete pSecondHash;
+ }
+}
+
+// Signing functions
+bool OSSLRSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
+ ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (mechanism == AsymMech::RSA_PKCS)
+ {
+ // Separate implementation for RSA PKCS #1 signing without hash computation
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // In case of PKCS #1 signing the length of the input data may not exceed 40% of the
+ // modulus size
+ OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;
+
+ size_t allowedLen = osslKey->getN().size() - 11;
+
+ if (dataToSign.size() > allowedLen)
+ {
+ ERROR_MSG("Data to sign exceeds maximum for PKCS #1 signature");
+
+ return false;
+ }
+
+ // Perform the signature operation
+ signature.resize(osslKey->getN().size());
+
+ RSA* rsa = osslKey->getOSSLKey();
+
+ if (!RSA_blinding_on(rsa, NULL))
+ {
+ ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");
+
+ return false;
+ }
+
+ int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_PKCS1_PADDING);
+
+ RSA_blinding_off(rsa);
+
+ if (sigLen == -1)
+ {
+ ERROR_MSG("An error occurred while performing a PKCS #1 signature");
+
+ return false;
+ }
+
+ signature.resize(sigLen);
+
+ return true;
+ }
+ else if (mechanism == AsymMech::RSA_PKCS_PSS)
+ {
+ const RSA_PKCS_PSS_PARAMS *pssParam = (RSA_PKCS_PSS_PARAMS*)param;
+
+ // Separate implementation for RSA PKCS #1 signing without hash computation
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ if (pssParam == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS))
+ {
+ ERROR_MSG("Invalid parameters supplied");
+
+ return false;
+ }
+
+ size_t allowedLen;
+ const EVP_MD* hash = NULL;
+
+ switch (pssParam->hashAlg)
+ {
+ case HashAlgo::SHA1:
+ hash = EVP_sha1();
+ allowedLen = 20;
+ break;
+ case HashAlgo::SHA224:
+ hash = EVP_sha224();
+ allowedLen = 28;
+ break;
+ case HashAlgo::SHA256:
+ hash = EVP_sha256();
+ allowedLen = 32;
+ break;
+ case HashAlgo::SHA384:
+ hash = EVP_sha384();
+ allowedLen = 48;
+ break;
+ case HashAlgo::SHA512:
+ hash = EVP_sha512();
+ allowedLen = 64;
+ break;
+ default:
+ return false;
+ }
+
+ OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;
+
+ RSA* rsa = osslKey->getOSSLKey();
+
+ if (dataToSign.size() != allowedLen)
+ {
+ ERROR_MSG("Data to sign does not match expected (%d) for RSA PSS", (int)allowedLen);
+
+ return false;
+ }
+
+ size_t sLen = pssParam->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-allowedLen))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ return false;
+ }
+
+ ByteString em;
+ em.resize(osslKey->getN().size());
+
+ int status = RSA_padding_add_PKCS1_PSS_mgf1(rsa, &em[0], (unsigned char*) dataToSign.const_byte_str(), hash, hash, pssParam->sLen);
+ if (!status)
+ {
+ ERROR_MSG("Error in RSA PSS padding generation");
+
+ return false;
+ }
+
+
+ if (!RSA_blinding_on(rsa, NULL))
+ {
+ ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");
+
+ return false;
+ }
+
+ // Perform the signature operation
+ signature.resize(osslKey->getN().size());
+
+ int sigLen = RSA_private_encrypt(osslKey->getN().size(), &em[0], &signature[0], rsa, RSA_NO_PADDING);
+
+ RSA_blinding_off(rsa);
+
+ if (sigLen == -1)
+ {
+ ERROR_MSG("An error occurred while performing the RSA-PSS signature");
+
+ return false;
+ }
+
+ signature.resize(sigLen);
+
+ return true;
+ }
+ else if (mechanism == AsymMech::RSA)
+ {
+ // Separate implementation for raw RSA signing
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // In case of raw RSA, the length of the input data must match the length of the modulus
+ OSSLRSAPrivateKey* osslKey = (OSSLRSAPrivateKey*) privateKey;
+
+ if (dataToSign.size() != osslKey->getN().size())
+ {
+ ERROR_MSG("Size of data to sign does not match the modulus size");
+
+ return false;
+ }
+
+ // Perform the signature operation
+ signature.resize(osslKey->getN().size());
+
+ RSA* rsa = osslKey->getOSSLKey();
+
+ if (!RSA_blinding_on(rsa, NULL))
+ {
+ ERROR_MSG("Failed to turn on blinding for OpenSSL RSA key");
+
+ return false;
+ }
+
+ int sigLen = RSA_private_encrypt(dataToSign.size(), (unsigned char*) dataToSign.const_byte_str(), &signature[0], rsa, RSA_NO_PADDING);
+
+ RSA_blinding_off(rsa);
+
+ if (sigLen == -1)
+ {
+ ERROR_MSG("An error occurred while performing a raw RSA signature");
+
+ return false;
+ }
+
+ signature.resize(sigLen);
+
+ return true;
+ }
+ else
+ {
+ // Call default implementation
+ return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
+ }
+}
+
+bool OSSLRSA::signInit(PrivateKey* privateKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::signInit(privateKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ HashAlgo::Type hash1 = HashAlgo::Unknown;
+ HashAlgo::Type hash2 = HashAlgo::Unknown;
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA_MD5_PKCS:
+ hash1 = HashAlgo::MD5;
+ break;
+ case AsymMech::RSA_SHA1_PKCS:
+ hash1 = HashAlgo::SHA1;
+ break;
+ case AsymMech::RSA_SHA224_PKCS:
+ hash1 = HashAlgo::SHA224;
+ break;
+ case AsymMech::RSA_SHA256_PKCS:
+ hash1 = HashAlgo::SHA256;
+ break;
+ case AsymMech::RSA_SHA384_PKCS:
+ hash1 = HashAlgo::SHA384;
+ break;
+ case AsymMech::RSA_SHA512_PKCS:
+ hash1 = HashAlgo::SHA512;
+ break;
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-20))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA1;
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-28))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA224;
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-32))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA256;
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-48))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA384;
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((privateKey->getBitLength()+6)/8-2-64))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, privateKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA512;
+ break;
+ case AsymMech::RSA_SSL:
+ hash1 = HashAlgo::MD5;
+ hash2 = HashAlgo::SHA1;
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ pCurrentHash = CryptoFactory::i()->getHashAlgorithm(hash1);
+
+ if (pCurrentHash == NULL || !pCurrentHash->hashInit())
+ {
+ if (pCurrentHash != NULL)
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+ }
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ if (hash2 != HashAlgo::Unknown)
+ {
+ pSecondHash = CryptoFactory::i()->getHashAlgorithm(hash2);
+
+ if (pSecondHash == NULL || !pSecondHash->hashInit())
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ if (pSecondHash != NULL)
+ {
+ delete pSecondHash;
+ pSecondHash = NULL;
+ }
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool OSSLRSA::signUpdate(const ByteString& dataToSign)
+{
+ if (!AsymmetricAlgorithm::signUpdate(dataToSign))
+ {
+ return false;
+ }
+
+ if (!pCurrentHash->hashUpdate(dataToSign))
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ if ((pSecondHash != NULL) && !pSecondHash->hashUpdate(dataToSign))
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ delete pSecondHash;
+ pSecondHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::signFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLRSA::signFinal(ByteString& signature)
+{
+ // Save necessary state before calling super class signFinal
+ OSSLRSAPrivateKey* pk = (OSSLRSAPrivateKey*) currentPrivateKey;
+ AsymMech::Type mechanism = currentMechanism;
+
+ if (!AsymmetricAlgorithm::signFinal(signature))
+ {
+ return false;
+ }
+
+ ByteString firstHash, secondHash;
+
+ bool bFirstResult = pCurrentHash->hashFinal(firstHash);
+ bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;
+
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ if (pSecondHash != NULL)
+ {
+ delete pSecondHash;
+
+ pSecondHash = NULL;
+ }
+
+ if (!bFirstResult || !bSecondResult)
+ {
+ return false;
+ }
+
+ ByteString digest = firstHash + secondHash;
+
+ // Resize the data block for the signature to the modulus size of the key
+ signature.resize(pk->getN().size());
+
+ // Determine the signature NID type
+ int type = 0;
+ bool isPSS = false;
+ const EVP_MD* hash = NULL;
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA_MD5_PKCS:
+ type = NID_md5;
+ break;
+ case AsymMech::RSA_SHA1_PKCS:
+ type = NID_sha1;
+ break;
+ case AsymMech::RSA_SHA224_PKCS:
+ type = NID_sha224;
+ break;
+ case AsymMech::RSA_SHA256_PKCS:
+ type = NID_sha256;
+ break;
+ case AsymMech::RSA_SHA384_PKCS:
+ type = NID_sha384;
+ break;
+ case AsymMech::RSA_SHA512_PKCS:
+ type = NID_sha512;
+ break;
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha1();
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha224();
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha256();
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha384();
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha512();
+ break;
+ case AsymMech::RSA_SSL:
+ type = NID_md5_sha1;
+ break;
+ default:
+ break;
+ }
+
+ // Perform the signature operation
+ unsigned int sigLen = signature.size();
+
+ RSA* rsa = pk->getOSSLKey();
+
+ if (!RSA_blinding_on(rsa, NULL))
+ {
+ ERROR_MSG("Failed to turn blinding on for OpenSSL RSA key");
+
+ return false;
+ }
+
+ bool rv;
+ int result;
+
+ if (isPSS)
+ {
+ ByteString em;
+ em.resize(pk->getN().size());
+
+ result = (RSA_padding_add_PKCS1_PSS(pk->getOSSLKey(), &em[0], &digest[0],
+ hash, sLen) == 1);
+ if (!result)
+ {
+ ERROR_MSG("RSA PSS padding failed (0x%08X)", ERR_get_error());
+ rv = false;
+ }
+ else
+ {
+ result = RSA_private_encrypt(em.size(), &em[0], &signature[0],
+ pk->getOSSLKey(), RSA_NO_PADDING);
+ if (result >= 0)
+ {
+ sigLen = result;
+ rv = true;
+ }
+ else
+ {
+ ERROR_MSG("RSA private encrypt failed (0x%08X)", ERR_get_error());
+ rv = false;
+ }
+ }
+ }
+ else
+ {
+ result = RSA_sign(type, &digest[0], digest.size(), &signature[0],
+ &sigLen, pk->getOSSLKey());
+ if (result > 0)
+ {
+ rv = true;
+ }
+ else
+ {
+ ERROR_MSG("RSA sign failed (0x%08X)", ERR_get_error());
+ rv = false;
+ }
+ }
+
+ RSA_blinding_off(rsa);
+
+ signature.resize(sigLen);
+
+ return rv;
+}
+
+// Verification functions
+bool OSSLRSA::verify(PublicKey* publicKey, const ByteString& originalData,
+ const ByteString& signature, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (mechanism == AsymMech::RSA_PKCS)
+ {
+ // Specific implementation for PKCS #1 only verification; originalData is assumed to contain
+ // a digestInfo structure and verification is performed by comparing originalData to the data
+ // recovered from the signature
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(OSSLRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Perform the RSA public key operation
+ OSSLRSAPublicKey* osslKey = (OSSLRSAPublicKey*) publicKey;
+
+ ByteString recoveredData;
+
+ recoveredData.resize(osslKey->getN().size());
+
+ RSA* rsa = osslKey->getOSSLKey();
+
+ int retLen = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &recoveredData[0], rsa, RSA_PKCS1_PADDING);
+
+ if (retLen == -1)
+ {
+ ERROR_MSG("Public key operation failed");
+
+ return false;
+ }
+
+ recoveredData.resize(retLen);
+
+ return (originalData == recoveredData);
+ }
+ else if (mechanism == AsymMech::RSA_PKCS_PSS)
+ {
+ const RSA_PKCS_PSS_PARAMS *pssParam = (RSA_PKCS_PSS_PARAMS*)param;
+
+ if (pssParam == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS))
+ {
+ ERROR_MSG("Invalid parameters supplied");
+
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(OSSLRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Perform the RSA public key operation
+ OSSLRSAPublicKey* osslKey = (OSSLRSAPublicKey*) publicKey;
+
+ ByteString recoveredData;
+
+ recoveredData.resize(osslKey->getN().size());
+
+ RSA* rsa = osslKey->getOSSLKey();
+
+ int retLen = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &recoveredData[0], rsa, RSA_NO_PADDING);
+
+ if (retLen == -1)
+ {
+ ERROR_MSG("Public key operation failed");
+
+ return false;
+ }
+
+ recoveredData.resize(retLen);
+
+ size_t allowedLen;
+ const EVP_MD* hash = NULL;
+
+ switch (pssParam->hashAlg)
+ {
+ case HashAlgo::SHA1:
+ hash = EVP_sha1();
+ allowedLen = 20;
+ break;
+ case HashAlgo::SHA224:
+ hash = EVP_sha224();
+ allowedLen = 28;
+ break;
+ case HashAlgo::SHA256:
+ hash = EVP_sha256();
+ allowedLen = 32;
+ break;
+ case HashAlgo::SHA384:
+ hash = EVP_sha384();
+ allowedLen = 48;
+ break;
+ case HashAlgo::SHA512:
+ hash = EVP_sha512();
+ allowedLen = 64;
+ break;
+ default:
+ return false;
+ }
+
+ if (originalData.size() != allowedLen) {
+ return false;
+ }
+
+ size_t sLen = pssParam->sLen;
+ if (sLen > ((osslKey->getBitLength()+6)/8-2-allowedLen))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, osslKey->getBitLength());
+ return false;
+ }
+
+ int status = RSA_verify_PKCS1_PSS_mgf1(rsa, (unsigned char*)originalData.const_byte_str(), hash, hash, (unsigned char*) recoveredData.const_byte_str(), pssParam->sLen);
+
+ return (status == 1);
+ }
+ else if (mechanism == AsymMech::RSA)
+ {
+ // Specific implementation for raw RSA verifiction; originalData is assumed to contain the
+ // full input data used to compute the signature and verification is performed by comparing
+ // originalData to the data recovered from the signature
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(OSSLRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Perform the RSA public key operation
+ OSSLRSAPublicKey* osslKey = (OSSLRSAPublicKey*) publicKey;
+
+ ByteString recoveredData;
+
+ recoveredData.resize(osslKey->getN().size());
+
+ RSA* rsa = osslKey->getOSSLKey();
+
+ int retLen = RSA_public_decrypt(signature.size(), (unsigned char*) signature.const_byte_str(), &recoveredData[0], rsa, RSA_NO_PADDING);
+
+ if (retLen == -1)
+ {
+ ERROR_MSG("Public key operation failed");
+
+ return false;
+ }
+
+ recoveredData.resize(retLen);
+
+ return (originalData == recoveredData);
+ }
+ else
+ {
+ // Call the generic function
+ return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
+ }
+}
+
+bool OSSLRSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
+ const void* param /* = NULL */, const size_t paramLen /* = 0 */)
+{
+ if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
+ {
+ return false;
+ }
+
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(OSSLRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ HashAlgo::Type hash1 = HashAlgo::Unknown;
+ HashAlgo::Type hash2 = HashAlgo::Unknown;
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA_MD5_PKCS:
+ hash1 = HashAlgo::MD5;
+ break;
+ case AsymMech::RSA_SHA1_PKCS:
+ hash1 = HashAlgo::SHA1;
+ break;
+ case AsymMech::RSA_SHA224_PKCS:
+ hash1 = HashAlgo::SHA224;
+ break;
+ case AsymMech::RSA_SHA256_PKCS:
+ hash1 = HashAlgo::SHA256;
+ break;
+ case AsymMech::RSA_SHA384_PKCS:
+ hash1 = HashAlgo::SHA384;
+ break;
+ case AsymMech::RSA_SHA512_PKCS:
+ hash1 = HashAlgo::SHA512;
+ break;
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-20))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA1;
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-28))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA224;
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-32))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA256;
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-48))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA384;
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
+ ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
+ {
+ ERROR_MSG("Invalid parameters");
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
+ if (sLen > ((publicKey->getBitLength()+6)/8-2-64))
+ {
+ ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
+ (unsigned long)sLen, publicKey->getBitLength());
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+ return false;
+ }
+ hash1 = HashAlgo::SHA512;
+ break;
+ case AsymMech::RSA_SSL:
+ hash1 = HashAlgo::MD5;
+ hash2 = HashAlgo::SHA1;
+ break;
+ default:
+ ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ pCurrentHash = CryptoFactory::i()->getHashAlgorithm(hash1);
+
+ if (pCurrentHash == NULL || !pCurrentHash->hashInit())
+ {
+ if (pCurrentHash != NULL)
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+ }
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ if (hash2 != HashAlgo::Unknown)
+ {
+ pSecondHash = CryptoFactory::i()->getHashAlgorithm(hash2);
+
+ if (pSecondHash == NULL || !pSecondHash->hashInit())
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ if (pSecondHash != NULL)
+ {
+ delete pSecondHash;
+ pSecondHash = NULL;
+ }
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool OSSLRSA::verifyUpdate(const ByteString& originalData)
+{
+ if (!AsymmetricAlgorithm::verifyUpdate(originalData))
+ {
+ return false;
+ }
+
+ if (!pCurrentHash->hashUpdate(originalData))
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ if ((pSecondHash != NULL) && !pSecondHash->hashUpdate(originalData))
+ {
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ delete pSecondHash;
+ pSecondHash = NULL;
+
+ ByteString dummy;
+ AsymmetricAlgorithm::verifyFinal(dummy);
+
+ return false;
+ }
+
+ return true;
+}
+
+bool OSSLRSA::verifyFinal(const ByteString& signature)
+{
+ // Save necessary state before calling super class verifyFinal
+ OSSLRSAPublicKey* pk = (OSSLRSAPublicKey*) currentPublicKey;
+ AsymMech::Type mechanism = currentMechanism;
+
+ if (!AsymmetricAlgorithm::verifyFinal(signature))
+ {
+ return false;
+ }
+
+ ByteString firstHash, secondHash;
+
+ bool bFirstResult = pCurrentHash->hashFinal(firstHash);
+ bool bSecondResult = (pSecondHash != NULL) ? pSecondHash->hashFinal(secondHash) : true;
+
+ delete pCurrentHash;
+ pCurrentHash = NULL;
+
+ if (pSecondHash != NULL)
+ {
+ delete pSecondHash;
+
+ pSecondHash = NULL;
+ }
+
+ if (!bFirstResult || !bSecondResult)
+ {
+ return false;
+ }
+
+ ByteString digest = firstHash + secondHash;
+
+ // Determine the signature NID type
+ int type = 0;
+ bool isPSS = false;
+ const EVP_MD* hash = NULL;
+
+ switch (mechanism)
+ {
+ case AsymMech::RSA_MD5_PKCS:
+ type = NID_md5;
+ break;
+ case AsymMech::RSA_SHA1_PKCS:
+ type = NID_sha1;
+ break;
+ case AsymMech::RSA_SHA224_PKCS:
+ type = NID_sha224;
+ break;
+ case AsymMech::RSA_SHA256_PKCS:
+ type = NID_sha256;
+ break;
+ case AsymMech::RSA_SHA384_PKCS:
+ type = NID_sha384;
+ break;
+ case AsymMech::RSA_SHA512_PKCS:
+ type = NID_sha512;
+ break;
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha1();
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha224();
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha256();
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha384();
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ isPSS = true;
+ hash = EVP_sha512();
+ break;
+ case AsymMech::RSA_SSL:
+ type = NID_md5_sha1;
+ break;
+ default:
+ break;
+ }
+
+ // Perform the verify operation
+ bool rv;
+
+ if (isPSS)
+ {
+ ByteString plain;
+ plain.resize(pk->getN().size());
+ int result = RSA_public_decrypt(signature.size(),
+ (unsigned char*) signature.const_byte_str(),
+ &plain[0],
+ pk->getOSSLKey(),
+ RSA_NO_PADDING);
+ if (result < 0)
+ {
+ rv = false;
+ ERROR_MSG("RSA public decrypt failed (0x%08X)", ERR_get_error());
+ }
+ else
+ {
+ plain.resize(result);
+ result = RSA_verify_PKCS1_PSS(pk->getOSSLKey(), &digest[0],
+ hash, &plain[0], sLen);
+ if (result == 1)
+ {
+ rv = true;
+ }
+ else
+ {
+ rv = false;
+ ERROR_MSG("RSA PSS verify failed (0x%08X)", ERR_get_error());
+ }
+ }
+ }
+ else
+ {
+ rv = (RSA_verify(type, &digest[0], digest.size(), (unsigned char*) signature.const_byte_str(), signature.size(), pk->getOSSLKey()) == 1);
+
+ if (!rv) ERROR_MSG("RSA verify failed (0x%08X)", ERR_get_error());
+ }
+
+ return rv;
+}
+
+// Encryption functions
+bool OSSLRSA::encrypt(PublicKey* publicKey, const ByteString& data,
+ ByteString& encryptedData, const AsymMech::Type padding)
+{
+ // Check if the public key is the right type
+ if (!publicKey->isOfType(OSSLRSAPublicKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Retrieve the OpenSSL key object
+ RSA* rsa = ((OSSLRSAPublicKey*) publicKey)->getOSSLKey();
+
+ // Check the data and padding algorithm
+ int osslPadding = 0;
+
+ if (padding == AsymMech::RSA_PKCS)
+ {
+ // The size of the input data cannot be more than the modulus
+ // length of the key - 11
+ if (data.size() > (size_t) (RSA_size(rsa) - 11))
+ {
+ ERROR_MSG("Too much data supplied for RSA PKCS #1 encryption");
+
+ return false;
+ }
+
+ osslPadding = RSA_PKCS1_PADDING;
+ }
+ else if (padding == AsymMech::RSA_PKCS_OAEP)
+ {
+ // The size of the input data cannot be more than the modulus
+ // length of the key - 41
+ if (data.size() > (size_t) (RSA_size(rsa) - 41))
+ {
+ ERROR_MSG("Too much data supplied for RSA OAEP encryption");
+
+ return false;
+ }
+
+ osslPadding = RSA_PKCS1_OAEP_PADDING;
+ }
+ else if (padding == AsymMech::RSA)
+ {
+ // The size of the input data should be exactly equal to the modulus length
+ if (data.size() != (size_t) RSA_size(rsa))
+ {
+ ERROR_MSG("Incorrect amount of input data supplied for raw RSA encryption");
+
+ return false;
+ }
+
+ osslPadding = RSA_NO_PADDING;
+ }
+ else
+ {
+ ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
+
+ return false;
+ }
+
+ // Perform the RSA operation
+ encryptedData.resize(RSA_size(rsa));
+
+ if (RSA_public_encrypt(data.size(), (unsigned char*) data.const_byte_str(), &encryptedData[0], rsa, osslPadding) == -1)
+ {
+ ERROR_MSG("RSA public key encryption failed (0x%08X)", ERR_get_error());
+
+ return false;
+ }
+
+ return true;
+}
+
+// Decryption functions
+bool OSSLRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData,
+ ByteString& data, const AsymMech::Type padding)
+{
+ // Check if the private key is the right type
+ if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
+ {
+ ERROR_MSG("Invalid key type supplied");
+
+ return false;
+ }
+
+ // Retrieve the OpenSSL key object
+ RSA* rsa = ((OSSLRSAPrivateKey*) privateKey)->getOSSLKey();
+
+ // Check the input size
+ if (encryptedData.size() != (size_t) RSA_size(rsa))
+ {
+ ERROR_MSG("Invalid amount of input data supplied for RSA decryption");
+
+ return false;
+ }
+
+ // Determine the OpenSSL padding algorithm
+ int osslPadding = 0;
+
+ switch (padding)
+ {
+ case AsymMech::RSA_PKCS:
+ osslPadding = RSA_PKCS1_PADDING;
+ break;
+ case AsymMech::RSA_PKCS_OAEP:
+ osslPadding = RSA_PKCS1_OAEP_PADDING;
+ break;
+ case AsymMech::RSA:
+ osslPadding = RSA_NO_PADDING;
+ break;
+ default:
+ ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
+ return false;
+ }
+
+ // Perform the RSA operation
+ data.resize(RSA_size(rsa));
+
+ int decSize = RSA_private_decrypt(encryptedData.size(), (unsigned char*) encryptedData.const_byte_str(), &data[0], rsa, osslPadding);
+
+ if (decSize == -1)
+ {
+ ERROR_MSG("RSA private key decryption failed (0x%08X)", ERR_get_error());
+
+ return false;
+ }
+
+ data.resize(decSize);
+
+ return true;
+}
+
+// Key factory
+bool OSSLRSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
+{
+ // Check parameters
+ if ((ppKeyPair == NULL) ||
+ (parameters == NULL))
+ {
+ return false;
+ }
+
+ if (!parameters->areOfType(RSAParameters::type))
+ {
+ ERROR_MSG("Invalid parameters supplied for RSA key generation");
+
+ return false;
+ }
+
+ RSAParameters* params = (RSAParameters*) parameters;
+
+ if (params->getBitLength() < getMinKeySize() || params->getBitLength() > getMaxKeySize())
+ {
+ ERROR_MSG("This RSA key size (%lu) is not supported", params->getBitLength());
+
+ return false;
+ }
+
+ if (params->getBitLength() < 1024)
+ {
+ WARNING_MSG("Using an RSA key size < 1024 bits is not recommended");
+ }
+
+ // Retrieve the desired public exponent
+ unsigned long e = params->getE().long_val();
+
+ // Check the public exponent
+ if ((e == 0) || (e % 2 != 1))
+ {
+ ERROR_MSG("Invalid RSA public exponent %d", e);
+
+ return false;
+ }
+
+ // Generate the key-pair
+ RSA* rsa = RSA_new();
+ if (rsa == NULL)
+ {
+ ERROR_MSG("Failed to instantiate OpenSSL RSA object");
+
+ return false;
+ }
+
+ BIGNUM* bn_e = OSSL::byteString2bn(params->getE());
+
+ // Check if the key was successfully generated
+ if (!RSA_generate_key_ex(rsa, params->getBitLength(), bn_e, NULL))
+ {
+ ERROR_MSG("RSA key generation failed (0x%08X)", ERR_get_error());
+ BN_free(bn_e);
+ RSA_free(rsa);
+
+ return false;
+ }
+ BN_free(bn_e);
+
+ // Create an asymmetric key-pair object to return
+ OSSLRSAKeyPair* kp = new OSSLRSAKeyPair();
+
+ ((OSSLRSAPublicKey*) kp->getPublicKey())->setFromOSSL(rsa);
+ ((OSSLRSAPrivateKey*) kp->getPrivateKey())->setFromOSSL(rsa);
+
+ *ppKeyPair = kp;
+
+ // Release the key
+ RSA_free(rsa);
+
+ return true;
+}
+
+unsigned long OSSLRSA::getMinKeySize()
+{
+#ifdef WITH_FIPS
+ // OPENSSL_RSA_FIPS_MIN_MODULUS_BITS is 1024
+ return 1024;
+#else
+ return 512;
+#endif
+}
+
+unsigned long OSSLRSA::getMaxKeySize()
+{
+ return OPENSSL_RSA_MAX_MODULUS_BITS;
+}
+
+bool OSSLRSA::reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppKeyPair == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ ByteString dPub = ByteString::chainDeserialise(serialisedData);
+ ByteString dPriv = ByteString::chainDeserialise(serialisedData);
+
+ OSSLRSAKeyPair* kp = new OSSLRSAKeyPair();
+
+ bool rv = true;
+
+ if (!((RSAPublicKey*) kp->getPublicKey())->deserialise(dPub))
+ {
+ rv = false;
+ }
+
+ if (!((RSAPrivateKey*) kp->getPrivateKey())->deserialise(dPriv))
+ {
+ rv = false;
+ }
+
+ if (!rv)
+ {
+ delete kp;
+
+ return false;
+ }
+
+ *ppKeyPair = kp;
+
+ return true;
+}
+
+bool OSSLRSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPublicKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLRSAPublicKey* pub = new OSSLRSAPublicKey();
+
+ if (!pub->deserialise(serialisedData))
+ {
+ delete pub;
+
+ return false;
+ }
+
+ *ppPublicKey = pub;
+
+ return true;
+}
+
+bool OSSLRSA::reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData)
+{
+ // Check input
+ if ((ppPrivateKey == NULL) ||
+ (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ OSSLRSAPrivateKey* priv = new OSSLRSAPrivateKey();
+
+ if (!priv->deserialise(serialisedData))
+ {
+ delete priv;
+
+ return false;
+ }
+
+ *ppPrivateKey = priv;
+
+ return true;
+}
+
+PublicKey* OSSLRSA::newPublicKey()
+{
+ return (PublicKey*) new OSSLRSAPublicKey();
+}
+
+PrivateKey* OSSLRSA::newPrivateKey()
+{
+ return (PrivateKey*) new OSSLRSAPrivateKey();
+}
+
+AsymmetricParameters* OSSLRSA::newParameters()
+{
+ return (AsymmetricParameters*) new RSAParameters();
+}
+
+bool OSSLRSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
+{
+ // Check input parameters
+ if ((ppParams == NULL) || (serialisedData.size() == 0))
+ {
+ return false;
+ }
+
+ RSAParameters* params = new RSAParameters();
+
+ if (!params->deserialise(serialisedData))
+ {
+ delete params;
+
+ return false;
+ }
+
+ *ppParams = params;
+
+ return true;
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSA.h b/SoftHSMv2/src/lib/crypto/OSSLRSA.h
new file mode 100644
index 0000000..5b7db6d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSA.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSA.h
+
+ OpenSSL RSA asymmetric algorithm implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLRSA_H
+#define _SOFTHSM_V2_OSSLRSA_H
+
+#include "config.h"
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include <openssl/rsa.h>
+
+class OSSLRSA : public AsymmetricAlgorithm
+{
+public:
+ // Constructor
+ OSSLRSA();
+
+ // Destructor
+ virtual ~OSSLRSA();
+
+ // Signing functions
+ virtual bool sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signInit(PrivateKey* privateKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool signUpdate(const ByteString& dataToSign);
+ virtual bool signFinal(ByteString& signature);
+
+ // Verification functions
+ virtual bool verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism, const void* param = NULL, const size_t paramLen = 0);
+ virtual bool verifyUpdate(const ByteString& originalData);
+ virtual bool verifyFinal(const ByteString& signature);
+
+ // Encryption functions
+ virtual bool encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const AsymMech::Type padding);
+
+ // Decryption functions
+ virtual bool decrypt(PrivateKey* privateKey, const ByteString& encryptedData, ByteString& data, const AsymMech::Type padding);
+
+ // Key factory
+ virtual bool generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* rng = NULL);
+ virtual unsigned long getMinKeySize();
+ virtual unsigned long getMaxKeySize();
+ virtual bool reconstructKeyPair(AsymmetricKeyPair** ppKeyPair, ByteString& serialisedData);
+ virtual bool reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData);
+ virtual bool reconstructPrivateKey(PrivateKey** ppPrivateKey, ByteString& serialisedData);
+ virtual bool reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData);
+ virtual PublicKey* newPublicKey();
+ virtual PrivateKey* newPrivateKey();
+ virtual AsymmetricParameters* newParameters();
+
+private:
+ HashAlgorithm* pCurrentHash;
+ HashAlgorithm* pSecondHash;
+ size_t sLen;
+};
+
+#endif // !_SOFTHSM_V2_OSSLRSA_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.cpp b/SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.cpp
new file mode 100644
index 0000000..6465d9c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSAKeyPair.cpp
+
+ OpenSSL RSA key-pair class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLRSAKeyPair.h"
+
+// Set the public key
+void OSSLRSAKeyPair::setPublicKey(OSSLRSAPublicKey& publicKey)
+{
+ pubKey = publicKey;
+}
+
+// Set the private key
+void OSSLRSAKeyPair::setPrivateKey(OSSLRSAPrivateKey& privateKey)
+{
+ privKey = privateKey;
+}
+
+// Return the public key
+PublicKey* OSSLRSAKeyPair::getPublicKey()
+{
+ return &pubKey;
+}
+
+const PublicKey* OSSLRSAKeyPair::getConstPublicKey() const
+{
+ return &pubKey;
+}
+
+// Return the private key
+PrivateKey* OSSLRSAKeyPair::getPrivateKey()
+{
+ return &privKey;
+}
+
+const PrivateKey* OSSLRSAKeyPair::getConstPrivateKey() const
+{
+ return &privKey;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.h b/SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.h
new file mode 100644
index 0000000..546ba96
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSAKeyPair.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSAKeyPair.h
+
+ OpenSSL RSA key-pair class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLRSAKEYPAIR_H
+#define _SOFTHSM_V2_OSSLRSAKEYPAIR_H
+
+#include "config.h"
+#include "AsymmetricKeyPair.h"
+#include "OSSLRSAPublicKey.h"
+#include "OSSLRSAPrivateKey.h"
+
+class OSSLRSAKeyPair : public AsymmetricKeyPair
+{
+public:
+ // Set the public key
+ void setPublicKey(OSSLRSAPublicKey& publicKey);
+
+ // Set the private key
+ void setPrivateKey(OSSLRSAPrivateKey& privateKey);
+
+ // Return the public key
+ virtual PublicKey* getPublicKey();
+ virtual const PublicKey* getConstPublicKey() const;
+
+ // Return the private key
+ virtual PrivateKey* getPrivateKey();
+ virtual const PrivateKey* getConstPrivateKey() const;
+
+private:
+ // The public key
+ OSSLRSAPublicKey pubKey;
+
+ // The private key
+ OSSLRSAPrivateKey privKey;
+};
+
+#endif // !_SOFTHSM_V2_OSSLRSAKEYPAIR_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.cpp
new file mode 100644
index 0000000..26065cf
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.cpp
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSAPrivateKey.cpp
+
+ OpenSSL RSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLComp.h"
+#include "OSSLRSAPrivateKey.h"
+#include "OSSLUtil.h"
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+#include <string.h>
+
+// Constructors
+OSSLRSAPrivateKey::OSSLRSAPrivateKey()
+{
+ rsa = NULL;
+}
+
+OSSLRSAPrivateKey::OSSLRSAPrivateKey(const RSA* inRSA)
+{
+ rsa = NULL;
+
+ setFromOSSL(inRSA);
+}
+
+// Destructor
+OSSLRSAPrivateKey::~OSSLRSAPrivateKey()
+{
+ RSA_free(rsa);
+}
+
+// The type
+/*static*/ const char* OSSLRSAPrivateKey::type = "OpenSSL RSA Private Key";
+
+// Set from OpenSSL representation
+void OSSLRSAPrivateKey::setFromOSSL(const RSA* inRSA)
+{
+ const BIGNUM* bn_p = NULL;
+ const BIGNUM* bn_q = NULL;
+ const BIGNUM* bn_dmp1 = NULL;
+ const BIGNUM* bn_dmq1 = NULL;
+ const BIGNUM* bn_iqmp = NULL;
+ const BIGNUM* bn_n = NULL;
+ const BIGNUM* bn_e = NULL;
+ const BIGNUM* bn_d = NULL;
+
+ RSA_get0_factors(inRSA, &bn_p, &bn_q);
+ RSA_get0_crt_params(inRSA, &bn_dmp1, &bn_dmq1, &bn_iqmp);
+ RSA_get0_key(inRSA, &bn_n, &bn_e, &bn_d);
+
+ if (bn_p)
+ {
+ ByteString inP = OSSL::bn2ByteString(bn_p);
+ setP(inP);
+ }
+ if (bn_q)
+ {
+ ByteString inQ = OSSL::bn2ByteString(bn_q);
+ setQ(inQ);
+ }
+ if (bn_dmp1)
+ {
+ ByteString inDP1 = OSSL::bn2ByteString(bn_dmp1);
+ setDP1(inDP1);
+ }
+ if (bn_dmq1)
+ {
+ ByteString inDQ1 = OSSL::bn2ByteString(bn_dmq1);
+ setDQ1(inDQ1);
+ }
+ if (bn_iqmp)
+ {
+ ByteString inPQ = OSSL::bn2ByteString(bn_iqmp);
+ setPQ(inPQ);
+ }
+ if (bn_n)
+ {
+ ByteString inN = OSSL::bn2ByteString(bn_n);
+ setN(inN);
+ }
+ if (bn_e)
+ {
+ ByteString inE = OSSL::bn2ByteString(bn_e);
+ setE(inE);
+ }
+ if (bn_d)
+ {
+ ByteString inD = OSSL::bn2ByteString(bn_d);
+ setD(inD);
+ }
+}
+
+// Check if the key is of the given type
+bool OSSLRSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Setters for the RSA private key components
+void OSSLRSAPrivateKey::setP(const ByteString& inP)
+{
+ RSAPrivateKey::setP(inP);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPrivateKey::setQ(const ByteString& inQ)
+{
+ RSAPrivateKey::setQ(inQ);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPrivateKey::setPQ(const ByteString& inPQ)
+{
+ RSAPrivateKey::setPQ(inPQ);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPrivateKey::setDP1(const ByteString& inDP1)
+{
+ RSAPrivateKey::setDP1(inDP1);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPrivateKey::setDQ1(const ByteString& inDQ1)
+{
+ RSAPrivateKey::setDQ1(inDQ1);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPrivateKey::setD(const ByteString& inD)
+{
+ RSAPrivateKey::setD(inD);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+
+// Setters for the RSA public key components
+void OSSLRSAPrivateKey::setN(const ByteString& inN)
+{
+ RSAPrivateKey::setN(inN);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPrivateKey::setE(const ByteString& inE)
+{
+ RSAPrivateKey::setE(inE);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+// Encode into PKCS#8 DER
+ByteString OSSLRSAPrivateKey::PKCS8Encode()
+{
+ ByteString der;
+ if (rsa == NULL) createOSSLKey();
+ if (rsa == NULL) return der;
+ EVP_PKEY* pkey = EVP_PKEY_new();
+ if (pkey == NULL) return der;
+ if (!EVP_PKEY_set1_RSA(pkey, rsa))
+ {
+ EVP_PKEY_free(pkey);
+ return der;
+ }
+ PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey);
+ EVP_PKEY_free(pkey);
+ if (p8inf == NULL) return der;
+ int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL);
+ if (len < 0)
+ {
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ return der;
+ }
+ der.resize(len);
+ unsigned char* priv = &der[0];
+ int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (len2 != len) der.wipe();
+ return der;
+}
+
+// Decode from PKCS#8 BER
+bool OSSLRSAPrivateKey::PKCS8Decode(const ByteString& ber)
+{
+ int len = ber.size();
+ if (len <= 0) return false;
+ const unsigned char* priv = ber.const_byte_str();
+ PKCS8_PRIV_KEY_INFO* p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &priv, len);
+ if (p8 == NULL) return false;
+ EVP_PKEY* pkey = EVP_PKCS82PKEY(p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (pkey == NULL) return false;
+ RSA* key = EVP_PKEY_get1_RSA(pkey);
+ EVP_PKEY_free(pkey);
+ if (key == NULL) return false;
+ setFromOSSL(key);
+ RSA_free(key);
+ return true;
+}
+
+// Retrieve the OpenSSL representation of the key
+RSA* OSSLRSAPrivateKey::getOSSLKey()
+{
+ if (rsa == NULL) createOSSLKey();
+
+ return rsa;
+}
+
+// Create the OpenSSL representation of the key
+void OSSLRSAPrivateKey::createOSSLKey()
+{
+ if (rsa != NULL) return;
+
+ rsa = RSA_new();
+ if (rsa == NULL)
+ {
+ ERROR_MSG("Could not create RSA object");
+ return;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ RSA_set_method(rsa, FIPS_rsa_pkcs1_ssleay());
+ else
+ RSA_set_method(rsa, RSA_PKCS1_SSLeay());
+#else
+ RSA_set_method(rsa, RSA_PKCS1_SSLeay());
+#endif
+
+#else
+ RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
+#endif
+
+ BIGNUM* bn_p = OSSL::byteString2bn(p);
+ BIGNUM* bn_q = OSSL::byteString2bn(q);
+ BIGNUM* bn_dmp1 = OSSL::byteString2bn(dp1);
+ BIGNUM* bn_dmq1 = OSSL::byteString2bn(dq1);
+ BIGNUM* bn_iqmp = OSSL::byteString2bn(pq);
+ BIGNUM* bn_n = OSSL::byteString2bn(n);
+ BIGNUM* bn_e = OSSL::byteString2bn(e);
+ BIGNUM* bn_d = OSSL::byteString2bn(d);
+
+ RSA_set0_factors(rsa, bn_p, bn_q);
+ RSA_set0_crt_params(rsa, bn_dmp1, bn_dmq1, bn_iqmp);
+ RSA_set0_key(rsa, bn_n, bn_e, bn_d);
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.h
new file mode 100644
index 0000000..bb876d5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSAPrivateKey.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSAPrivateKey.h
+
+ OpenSSL RSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLRSAPRIVATEKEY_H
+#define _SOFTHSM_V2_OSSLRSAPRIVATEKEY_H
+
+#include "config.h"
+#include "RSAPrivateKey.h"
+#include <openssl/rsa.h>
+
+class OSSLRSAPrivateKey : public RSAPrivateKey
+{
+public:
+ // Constructors
+ OSSLRSAPrivateKey();
+
+ OSSLRSAPrivateKey(const RSA* inRSA);
+
+ // Destructor
+ virtual ~OSSLRSAPrivateKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the RSA private key components
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setPQ(const ByteString& inPQ);
+ virtual void setDP1(const ByteString& inDP1);
+ virtual void setDQ1(const ByteString& inDQ1);
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the RSA public key components
+ virtual void setN(const ByteString& inN);
+ virtual void setE(const ByteString& inE);
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode();
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const RSA* inRSA);
+
+ // Retrieve the OpenSSL representation of the key
+ RSA* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ RSA* rsa;
+
+ // Create the OpenSSL representation of the key
+ void createOSSLKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLRSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.cpp
new file mode 100644
index 0000000..2a6893b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSAPublicKey.cpp
+
+ OpenSSL RSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLComp.h"
+#include "OSSLRSAPublicKey.h"
+#include "OSSLUtil.h"
+#include <string.h>
+#include <openssl/bn.h>
+#ifdef WITH_FIPS
+#include <openssl/fips.h>
+#endif
+
+// Constructors
+OSSLRSAPublicKey::OSSLRSAPublicKey()
+{
+ rsa = NULL;
+}
+
+OSSLRSAPublicKey::OSSLRSAPublicKey(const RSA* inRSA)
+{
+ rsa = NULL;
+
+ setFromOSSL(inRSA);
+}
+
+// Destructor
+OSSLRSAPublicKey::~OSSLRSAPublicKey()
+{
+ RSA_free(rsa);
+}
+
+// The type
+/*static*/ const char* OSSLRSAPublicKey::type = "OpenSSL RSA Public Key";
+
+// Check if the key is of the given type
+bool OSSLRSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Set from OpenSSL representation
+void OSSLRSAPublicKey::setFromOSSL(const RSA* inRSA)
+{
+ const BIGNUM* bn_n = NULL;
+ const BIGNUM* bn_e = NULL;
+
+ RSA_get0_key(inRSA, &bn_n, &bn_e, NULL);
+
+ if (bn_n)
+ {
+ ByteString inN = OSSL::bn2ByteString(bn_n);
+ setN(inN);
+ }
+ if (bn_e)
+ {
+ ByteString inE = OSSL::bn2ByteString(bn_e);
+ setE(inE);
+ }
+}
+
+// Setters for the RSA public key components
+void OSSLRSAPublicKey::setN(const ByteString& inN)
+{
+ RSAPublicKey::setN(inN);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+void OSSLRSAPublicKey::setE(const ByteString& inE)
+{
+ RSAPublicKey::setE(inE);
+
+ if (rsa)
+ {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+}
+
+// Retrieve the OpenSSL representation of the key
+RSA* OSSLRSAPublicKey::getOSSLKey()
+{
+ if (rsa == NULL) createOSSLKey();
+
+ return rsa;
+}
+
+// Create the OpenSSL representation of the key
+void OSSLRSAPublicKey::createOSSLKey()
+{
+ if (rsa != NULL) return;
+
+ rsa = RSA_new();
+ if (rsa == NULL)
+ {
+ ERROR_MSG("Could not create RSA object");
+ return;
+ }
+
+ // Use the OpenSSL implementation and not any engine
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+
+#ifdef WITH_FIPS
+ if (FIPS_mode())
+ RSA_set_method(rsa, FIPS_rsa_pkcs1_ssleay());
+ else
+ RSA_set_method(rsa, RSA_PKCS1_SSLeay());
+#else
+ RSA_set_method(rsa, RSA_PKCS1_SSLeay());
+#endif
+
+#else
+ RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
+#endif
+
+ BIGNUM* bn_n = OSSL::byteString2bn(n);
+ BIGNUM* bn_e = OSSL::byteString2bn(e);
+
+ RSA_set0_key(rsa, bn_n, bn_e, NULL);
+}
diff --git a/SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.h b/SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.h
new file mode 100644
index 0000000..98f99f2
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLRSAPublicKey.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLRSAPublicKey.h
+
+ OpenSSL RSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLRSAPUBLICKEY_H
+#define _SOFTHSM_V2_OSSLRSAPUBLICKEY_H
+
+#include "config.h"
+#include "RSAPublicKey.h"
+#include <openssl/rsa.h>
+
+class OSSLRSAPublicKey : public RSAPublicKey
+{
+public:
+ // Constructors
+ OSSLRSAPublicKey();
+
+ OSSLRSAPublicKey(const RSA* inRSA);
+
+ // Destructor
+ virtual ~OSSLRSAPublicKey();
+
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Setters for the RSA public key components
+ virtual void setN(const ByteString& inN);
+ virtual void setE(const ByteString& inE);
+
+ // Set from OpenSSL representation
+ virtual void setFromOSSL(const RSA* inRSA);
+
+ // Retrieve the OpenSSL representation of the key
+ RSA* getOSSLKey();
+
+private:
+ // The internal OpenSSL representation
+ RSA* rsa;
+
+ // Create the OpenSSL representation of the key
+ void createOSSLKey();
+};
+
+#endif // !_SOFTHSM_V2_OSSLRSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA1.cpp b/SoftHSMv2/src/lib/crypto/OSSLSHA1.cpp
new file mode 100644
index 0000000..fcee390
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA1.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA1.h
+
+ OpenSSL SHA1 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLSHA1.h"
+#include <openssl/evp.h>
+
+int OSSLSHA1::getHashSize()
+{
+ return 20;
+}
+
+const EVP_MD* OSSLSHA1::getEVPHash() const
+{
+ return EVP_sha1();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA1.h b/SoftHSMv2/src/lib/crypto/OSSLSHA1.h
new file mode 100644
index 0000000..011803b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA1.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA1.h
+
+ OpenSSL SHA1 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLSHA1_H
+#define _SOFTHSM_V2_OSSLSHA1_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLSHA1 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLSHA1_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA224.cpp b/SoftHSMv2/src/lib/crypto/OSSLSHA224.cpp
new file mode 100644
index 0000000..7dacf56
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA224.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA224.h
+
+ OpenSSL SHA224 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLSHA224.h"
+#include <openssl/evp.h>
+
+int OSSLSHA224::getHashSize()
+{
+ return 28;
+}
+
+const EVP_MD* OSSLSHA224::getEVPHash() const
+{
+ return EVP_sha224();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA224.h b/SoftHSMv2/src/lib/crypto/OSSLSHA224.h
new file mode 100644
index 0000000..f83ddf7
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA224.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA224.h
+
+ OpenSSL SHA224 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLSHA224_H
+#define _SOFTHSM_V2_OSSLSHA224_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLSHA224 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLSHA224_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA256.cpp b/SoftHSMv2/src/lib/crypto/OSSLSHA256.cpp
new file mode 100644
index 0000000..d8b57b0
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA256.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA256.h
+
+ OpenSSL SHA256 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLSHA256.h"
+#include <openssl/evp.h>
+
+int OSSLSHA256::getHashSize()
+{
+ return 32;
+}
+
+const EVP_MD* OSSLSHA256::getEVPHash() const
+{
+ return EVP_sha256();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA256.h b/SoftHSMv2/src/lib/crypto/OSSLSHA256.h
new file mode 100644
index 0000000..1f22386
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA256.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA256.h
+
+ OpenSSL SHA256 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLSHA256_H
+#define _SOFTHSM_V2_OSSLSHA256_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLSHA256 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLSHA256_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA384.cpp b/SoftHSMv2/src/lib/crypto/OSSLSHA384.cpp
new file mode 100644
index 0000000..01b6fce
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA384.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA384.h
+
+ OpenSSL SHA384 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLSHA384.h"
+#include <openssl/evp.h>
+
+int OSSLSHA384::getHashSize()
+{
+ return 48;
+}
+
+const EVP_MD* OSSLSHA384::getEVPHash() const
+{
+ return EVP_sha384();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA384.h b/SoftHSMv2/src/lib/crypto/OSSLSHA384.h
new file mode 100644
index 0000000..9b93724
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA384.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA384.h
+
+ OpenSSL SHA384 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLSHA384_H
+#define _SOFTHSM_V2_OSSLSHA384_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLSHA384 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLSHA384_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA512.cpp b/SoftHSMv2/src/lib/crypto/OSSLSHA512.cpp
new file mode 100644
index 0000000..4533354
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA512.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA512.h
+
+ OpenSSL SHA512 implementation
+ *****************************************************************************/
+
+#include "config.h"
+#include "OSSLSHA512.h"
+#include <openssl/evp.h>
+
+int OSSLSHA512::getHashSize()
+{
+ return 64;
+}
+
+const EVP_MD* OSSLSHA512::getEVPHash() const
+{
+ return EVP_sha512();
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLSHA512.h b/SoftHSMv2/src/lib/crypto/OSSLSHA512.h
new file mode 100644
index 0000000..cb266d8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLSHA512.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLSHA512.h
+
+ OpenSSL SHA512 implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLSHA512_H
+#define _SOFTHSM_V2_OSSLSHA512_H
+
+#include "config.h"
+#include "OSSLEVPHashAlgorithm.h"
+#include <openssl/evp.h>
+
+class OSSLSHA512 : public OSSLEVPHashAlgorithm
+{
+ virtual int getHashSize();
+protected:
+ virtual const EVP_MD* getEVPHash() const;
+};
+
+#endif // !_SOFTHSM_V2_OSSLSHA512_H
+
diff --git a/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp b/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp
new file mode 100644
index 0000000..981bb98
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLUtil.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLUtil.h
+
+ OpenSSL convenience functions
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "OSSLUtil.h"
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+
+// Convert an OpenSSL BIGNUM to a ByteString
+ByteString OSSL::bn2ByteString(const BIGNUM* bn)
+{
+ ByteString rv;
+
+ if (bn != NULL)
+ {
+ rv.resize(BN_num_bytes(bn));
+ BN_bn2bin(bn, &rv[0]);
+ }
+
+ return rv;
+}
+
+// Convert a ByteString to an OpenSSL BIGNUM
+BIGNUM* OSSL::byteString2bn(const ByteString& byteString)
+{
+ if (byteString.size() == 0) return NULL;
+
+ return BN_bin2bn(byteString.const_byte_str(), byteString.size(), NULL);
+}
+
+#ifdef WITH_ECC
+// Convert an OpenSSL EC GROUP to a ByteString
+ByteString OSSL::grp2ByteString(const EC_GROUP* grp)
+{
+ ByteString rv;
+
+ if (grp != NULL)
+ {
+ rv.resize(i2d_ECPKParameters(grp, NULL));
+ unsigned char *p = &rv[0];
+ i2d_ECPKParameters(grp, &p);
+ }
+
+ return rv;
+}
+
+// Convert a ByteString to an OpenSSL EC GROUP
+EC_GROUP* OSSL::byteString2grp(const ByteString& byteString)
+{
+ const unsigned char *p = byteString.const_byte_str();
+ return d2i_ECPKParameters(NULL, &p, byteString.size());
+}
+
+// POINT_CONVERSION_UNCOMPRESSED 0x04
+
+// Convert an OpenSSL EC POINT in the given EC GROUP to a ByteString
+ByteString OSSL::pt2ByteString(const EC_POINT* pt, const EC_GROUP* grp)
+{
+ ByteString rv;
+
+ if (pt != NULL && grp != NULL)
+ {
+ size_t len = EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ // Definite, short
+ if (len <= 0x7f)
+ {
+ rv.resize(2 + len);
+ rv[0] = V_ASN1_OCTET_STRING;
+ rv[1] = len & 0x7f;
+ EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2], len, NULL);
+ }
+ // Definite, long
+ else
+ {
+ // Get the number of length octets
+ ByteString length(len);
+ unsigned int counter = 0;
+ while (length[counter] == 0 && counter < (length.size()-1)) counter++;
+ ByteString lengthOctets(&length[counter], length.size() - counter);
+
+ rv.resize(len + 2 + lengthOctets.size());
+ rv[0] = V_ASN1_OCTET_STRING;
+ rv[1] = 0x80 | lengthOctets.size();
+ memcpy(&rv[2], &lengthOctets[0], lengthOctets.size());
+ EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &rv[2 + lengthOctets.size()], len, NULL);
+ }
+ }
+
+ return rv;
+}
+
+// Convert a ByteString to an OpenSSL EC POINT in the given EC GROUP
+EC_POINT* OSSL::byteString2pt(const ByteString& byteString, const EC_GROUP* grp)
+{
+ size_t len = byteString.size();
+ size_t controlOctets = 2;
+ if (len < controlOctets)
+ {
+ ERROR_MSG("Undersized EC point");
+
+ return NULL;
+ }
+
+ ByteString repr = byteString;
+
+ if (repr[0] != V_ASN1_OCTET_STRING)
+ {
+ ERROR_MSG("EC point tag is not OCTET STRING");
+
+ return NULL;
+ }
+
+ // Definite, short
+ if (repr[1] < 0x80)
+ {
+ if (repr[1] != (len - controlOctets))
+ {
+ if (repr[1] < (len - controlOctets))
+ {
+ ERROR_MSG("Underrun EC point");
+ }
+ else
+ {
+ ERROR_MSG("Overrun EC point");
+ }
+
+ return NULL;
+ }
+ }
+ // Definite, long
+ else
+ {
+ size_t lengthOctets = repr[1] & 0x7f;
+ controlOctets += lengthOctets;
+
+ if (controlOctets >= repr.size())
+ {
+ ERROR_MSG("Undersized EC point");
+
+ return NULL;
+ }
+
+ ByteString length(&repr[2], lengthOctets);
+
+ if (length.long_val() != (len - controlOctets))
+ {
+ if (length.long_val() < (len - controlOctets))
+ {
+ ERROR_MSG("Underrun EC point");
+ }
+ else
+ {
+ ERROR_MSG("Overrun EC point");
+ }
+
+ return NULL;
+ }
+ }
+
+ EC_POINT* pt = EC_POINT_new(grp);
+ if (!EC_POINT_oct2point(grp, pt, &repr[controlOctets], len - controlOctets, NULL))
+ {
+ ERROR_MSG("EC_POINT_oct2point failed: %s", ERR_error_string(ERR_get_error(), NULL));
+ EC_POINT_free(pt);
+ return NULL;
+ }
+ return pt;
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/OSSLUtil.h b/SoftHSMv2/src/lib/crypto/OSSLUtil.h
new file mode 100644
index 0000000..f353cc6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/OSSLUtil.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ OSSLUtil.h
+
+ OpenSSL convenience functions
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_OSSLUTIL_H
+#define _SOFTHSM_V2_OSSLUTIL_H
+
+#include "config.h"
+#include "ByteString.h"
+#include <openssl/bn.h>
+#ifdef WITH_ECC
+#include <openssl/ec.h>
+#endif
+
+namespace OSSL
+{
+ // Convert an OpenSSL BIGNUM to a ByteString
+ ByteString bn2ByteString(const BIGNUM* bn);
+
+ // Convert a ByteString to an OpenSSL BIGNUM
+ BIGNUM* byteString2bn(const ByteString& byteString);
+
+#ifdef WITH_ECC
+ // Convert an OpenSSL EC GROUP to a ByteString
+ ByteString grp2ByteString(const EC_GROUP* grp);
+
+ // Convert a ByteString to an OpenSSL EC GROUP
+ EC_GROUP* byteString2grp(const ByteString& byteString);
+
+ // Convert an OpenSSL EC POINT in the given EC GROUP to a ByteString
+ ByteString pt2ByteString(const EC_POINT* pt, const EC_GROUP* grp);
+
+ // Convert a ByteString to an OpenSSL EC POINT in the given EC GROUP
+ EC_POINT* byteString2pt(const ByteString& byteString, const EC_GROUP* grp);
+#endif
+}
+
+#endif // !_SOFTHSM_V2_OSSLUTIL_H
+
diff --git a/SoftHSMv2/src/lib/crypto/PrivateKey.h b/SoftHSMv2/src/lib/crypto/PrivateKey.h
new file mode 100644
index 0000000..cb14539
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/PrivateKey.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ PrivateKey.h
+
+ Base class for private key classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_PRIVATEKEY_H
+#define _SOFTHSM_V2_PRIVATEKEY_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+#include <string>
+
+class PrivateKey : public Serialisable
+{
+public:
+ // Base constructors
+ PrivateKey() { }
+
+ PrivateKey(const PrivateKey& in);
+
+ // Destructor
+ virtual ~PrivateKey() { }
+
+ // Check if the private key is of the given type
+ virtual bool isOfType(const char* inType) = 0;
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const = 0;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const = 0;
+
+ // Serialisation
+ virtual ByteString serialise() const = 0;
+
+ // Encode into PKCS#8 DER
+ virtual ByteString PKCS8Encode() = 0;
+
+ // Decode from PKCS#8 BER
+ virtual bool PKCS8Decode(const ByteString& ber) = 0;
+};
+
+#endif // !_SOFTHSM_V2_PRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/PublicKey.h b/SoftHSMv2/src/lib/crypto/PublicKey.h
new file mode 100644
index 0000000..2207e8d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/PublicKey.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ PublicKey.h
+
+ Base class for public key classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_PUBLICKEY_H
+#define _SOFTHSM_V2_PUBLICKEY_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+
+class PublicKey : public Serialisable
+{
+public:
+ // Base constructors
+ PublicKey() { }
+
+ PublicKey(const PublicKey& /*in*/) { }
+
+ // Destructor
+ virtual ~PublicKey() { }
+
+ // Check if it is of the given type
+ virtual bool isOfType(const char* inType) = 0;
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const = 0;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const = 0;
+
+ // Serialisation
+ virtual ByteString serialise() const = 0;
+};
+
+#endif // !_SOFTHSM_V2_PUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/RNG.h b/SoftHSMv2/src/lib/crypto/RNG.h
new file mode 100644
index 0000000..ea0548f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RNG.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RNG.h
+
+ Base class for random number generator classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RNG_H
+#define _SOFTHSM_V2_RNG_H
+
+#include "config.h"
+#include "ByteString.h"
+
+struct RNGImpl
+{
+ enum Type
+ {
+ Unknown,
+ Default
+ };
+};
+
+class RNG
+{
+public:
+ // Base constructor
+ RNG() { }
+
+ // Destructor
+ virtual ~RNG() { }
+
+ // Generate random data
+ virtual bool generateRandom(ByteString& data, const size_t len) = 0;
+
+ // Seed the random pool
+ virtual void seed(ByteString& seedData) = 0;
+
+private:
+};
+
+#endif // !_SOFTHSM_V2_RNG_H
+
diff --git a/SoftHSMv2/src/lib/crypto/RSAParameters.cpp b/SoftHSMv2/src/lib/crypto/RSAParameters.cpp
new file mode 100644
index 0000000..26ba7a7
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RSAParameters.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSAParameters.h
+
+ RSA parameters (only used for key generation)
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "RSAParameters.h"
+#include <string.h>
+
+// The type
+/*static*/ const char* RSAParameters::type = "Generic RSA parameters";
+
+// Set the public exponent
+void RSAParameters::setE(const ByteString& inE)
+{
+ e = inE;
+}
+
+// Set the bit length
+void RSAParameters::setBitLength(const size_t inBitLen)
+{
+ bitLen = inBitLen;
+}
+
+// Get the public exponent
+const ByteString& RSAParameters::getE() const
+{
+ return e;
+}
+
+// Get the bit length
+size_t RSAParameters::getBitLength() const
+{
+ return bitLen;
+}
+
+// Are the parameters of the given type?
+bool RSAParameters::areOfType(const char* inType)
+{
+ return (strcmp(type, inType) == 0);
+}
+
+// Serialisation
+ByteString RSAParameters::serialise() const
+{
+ ByteString len(bitLen);
+
+ return e.serialise() + len.serialise();
+}
+
+bool RSAParameters::deserialise(ByteString& serialised)
+{
+ ByteString dE = ByteString::chainDeserialise(serialised);
+ ByteString dLen = ByteString::chainDeserialise(serialised);
+
+ if ((dE.size() == 0) ||
+ (dLen.size() == 0))
+ {
+ return false;
+ }
+
+ setE(dE);
+ setBitLength(dLen.long_val());
+
+ return true;
+}
diff --git a/SoftHSMv2/src/lib/crypto/RSAParameters.h b/SoftHSMv2/src/lib/crypto/RSAParameters.h
new file mode 100644
index 0000000..c8e748e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RSAParameters.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSAParameters.h
+
+ RSA parameters (only used for key generation)
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RSAPARAMETERS_H
+#define _SOFTHSM_V2_RSAPARAMETERS_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "AsymmetricParameters.h"
+
+class RSAParameters : public AsymmetricParameters
+{
+public:
+ // Base constructor
+ RSAParameters() : bitLen(0) { }
+
+ // The type
+ static const char* type;
+
+ // Set the public exponent
+ void setE(const ByteString& inE);
+
+ // Set the bit length
+ void setBitLength(const size_t inBitLen);
+
+ // Get the public exponent
+ const ByteString& getE() const;
+
+ // Get the bit length
+ size_t getBitLength() const;
+
+ // Are the parameters of the given type?
+ virtual bool areOfType(const char* inType);
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+private:
+ ByteString e;
+ size_t bitLen;
+};
+
+#endif // !_SOFTHSM_V2_RSAPARAMETERS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/RSAPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/RSAPrivateKey.cpp
new file mode 100644
index 0000000..7b3d43d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RSAPrivateKey.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSAPrivateKey.cpp
+
+ RSA private key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "RSAPrivateKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* RSAPrivateKey::type = "Abstract RSA private key";
+
+// Check if the key is of the given type
+bool RSAPrivateKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long RSAPrivateKey::getBitLength() const
+{
+ return getN().bits();
+}
+
+// Get the output length
+unsigned long RSAPrivateKey::getOutputLength() const
+{
+ // Also handle odd number of bits (bits % 8 != 0)
+ return (getBitLength() + 7) / 8;
+}
+
+// Setters for the RSA private key components
+void RSAPrivateKey::setP(const ByteString& inP)
+{
+ p = inP;
+}
+
+void RSAPrivateKey::setQ(const ByteString& inQ)
+{
+ q = inQ;
+}
+
+void RSAPrivateKey::setPQ(const ByteString& inPQ)
+{
+ pq = inPQ;
+}
+
+void RSAPrivateKey::setDP1(const ByteString& inDP1)
+{
+ dp1 = inDP1;
+}
+
+void RSAPrivateKey::setDQ1(const ByteString& inDQ1)
+{
+ dq1 = inDQ1;
+}
+
+void RSAPrivateKey::setD(const ByteString& inD)
+{
+ d = inD;
+}
+
+// Setters for the RSA public key components
+void RSAPrivateKey::setN(const ByteString& inN)
+{
+ n = inN;
+}
+
+void RSAPrivateKey::setE(const ByteString& inE)
+{
+ e = inE;
+}
+
+// Getters for the RSA private key components
+const ByteString& RSAPrivateKey::getP() const
+{
+ return p;
+}
+
+const ByteString& RSAPrivateKey::getQ() const
+{
+ return q;
+}
+
+const ByteString& RSAPrivateKey::getPQ() const
+{
+ return pq;
+}
+
+const ByteString& RSAPrivateKey::getDP1() const
+{
+ return dp1;
+}
+
+const ByteString& RSAPrivateKey::getDQ1() const
+{
+ return dq1;
+}
+
+const ByteString& RSAPrivateKey::getD() const
+{
+ return d;
+}
+
+// Getters for the RSA public key components
+const ByteString& RSAPrivateKey::getN() const
+{
+ return n;
+}
+
+const ByteString& RSAPrivateKey::getE() const
+{
+ return e;
+}
+
+// Serialisation
+ByteString RSAPrivateKey::serialise() const
+{
+ return p.serialise() +
+ q.serialise() +
+ pq.serialise() +
+ dp1.serialise() +
+ dq1.serialise() +
+ d.serialise() +
+ n.serialise() +
+ e.serialise();
+}
+
+bool RSAPrivateKey::deserialise(ByteString& serialised)
+{
+ ByteString dP = ByteString::chainDeserialise(serialised);
+ ByteString dQ = ByteString::chainDeserialise(serialised);
+ ByteString dPQ = ByteString::chainDeserialise(serialised);
+ ByteString dDP1 = ByteString::chainDeserialise(serialised);
+ ByteString dDQ1 = ByteString::chainDeserialise(serialised);
+ ByteString dD = ByteString::chainDeserialise(serialised);
+ ByteString dN = ByteString::chainDeserialise(serialised);
+ ByteString dE = ByteString::chainDeserialise(serialised);
+
+ if ((dD.size() == 0) ||
+ (dN.size() == 0) ||
+ (dE.size() == 0))
+ {
+ return false;
+ }
+
+ setP(dP);
+ setQ(dQ);
+ setPQ(dPQ);
+ setDP1(dDP1);
+ setDQ1(dDQ1);
+ setD(dD);
+ setN(dN);
+ setE(dE);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/RSAPrivateKey.h b/SoftHSMv2/src/lib/crypto/RSAPrivateKey.h
new file mode 100644
index 0000000..3c40c3c
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RSAPrivateKey.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSAPrivateKey.h
+
+ RSA private key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RSAPRIVATEKEY_H
+#define _SOFTHSM_V2_RSAPRIVATEKEY_H
+
+#include "config.h"
+#include "PrivateKey.h"
+
+class RSAPrivateKey : public PrivateKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the RSA private key components
+ virtual void setP(const ByteString& inP);
+ virtual void setQ(const ByteString& inQ);
+ virtual void setPQ(const ByteString& inPQ);
+ virtual void setDP1(const ByteString& inDP1);
+ virtual void setDQ1(const ByteString& inDQ1);
+ virtual void setD(const ByteString& inD);
+
+ // Setters for the RSA public key components
+ virtual void setN(const ByteString& inN);
+ virtual void setE(const ByteString& inE);
+
+ // Getters for the RSA private key components
+ virtual const ByteString& getP() const;
+ virtual const ByteString& getQ() const;
+ virtual const ByteString& getPQ() const;
+ virtual const ByteString& getDP1() const;
+ virtual const ByteString& getDQ1() const;
+ virtual const ByteString& getD() const;
+
+ // Getters for the RSA public key components
+ virtual const ByteString& getN() const;
+ virtual const ByteString& getE() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Private components
+ ByteString p,q,pq,dp1,dq1,d;
+
+ // Public components
+ ByteString n,e;
+};
+
+#endif // !_SOFTHSM_V2_RSAPRIVATEKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/RSAPublicKey.cpp b/SoftHSMv2/src/lib/crypto/RSAPublicKey.cpp
new file mode 100644
index 0000000..e0e05cd
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RSAPublicKey.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSAPublicKey.cpp
+
+ RSA public key class
+ *****************************************************************************/
+
+#include "config.h"
+#include "log.h"
+#include "RSAPublicKey.h"
+#include <string.h>
+
+// Set the type
+/*static*/ const char* RSAPublicKey::type = "Abstract RSA public key";
+
+// Check if the key is of the given type
+bool RSAPublicKey::isOfType(const char* inType)
+{
+ return !strcmp(type, inType);
+}
+
+// Get the bit length
+unsigned long RSAPublicKey::getBitLength() const
+{
+ return getN().bits();
+}
+
+// Get the output length
+unsigned long RSAPublicKey::getOutputLength() const
+{
+ // Also handle odd number of bits (bits % 8 != 0)
+ return (getBitLength() + 7) / 8;
+}
+
+// Setters for the RSA public key components
+void RSAPublicKey::setN(const ByteString& inN)
+{
+ n = inN;
+}
+
+void RSAPublicKey::setE(const ByteString& inE)
+{
+ e = inE;
+}
+
+// Getters for the RSA public key components
+const ByteString& RSAPublicKey::getN() const
+{
+ return n;
+}
+
+const ByteString& RSAPublicKey::getE() const
+{
+ return e;
+}
+
+// Serialisation
+ByteString RSAPublicKey::serialise() const
+{
+ return n.serialise() +
+ e.serialise();
+}
+
+bool RSAPublicKey::deserialise(ByteString& serialised)
+{
+ ByteString dN = ByteString::chainDeserialise(serialised);
+ ByteString dE = ByteString::chainDeserialise(serialised);
+
+ if ((dN.size() == 0) ||
+ (dE.size() == 0))
+ {
+ return false;
+ }
+
+ setN(dN);
+ setE(dE);
+
+ return true;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/RSAPublicKey.h b/SoftHSMv2/src/lib/crypto/RSAPublicKey.h
new file mode 100644
index 0000000..9256966
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/RSAPublicKey.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSAPublicKey.h
+
+ RSA public key class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RSAPUBLICKEY_H
+#define _SOFTHSM_V2_RSAPUBLICKEY_H
+
+#include "config.h"
+#include "PublicKey.h"
+
+class RSAPublicKey : public PublicKey
+{
+public:
+ // The type
+ static const char* type;
+
+ // Check if the key is of the given type
+ virtual bool isOfType(const char* inType);
+
+ // Get the bit length
+ virtual unsigned long getBitLength() const;
+
+ // Get the output length
+ virtual unsigned long getOutputLength() const;
+
+ // Setters for the RSA public key components
+ virtual void setN(const ByteString& inN);
+ virtual void setE(const ByteString& inE);
+
+ // Getters for the RSA public key components
+ virtual const ByteString& getN() const;
+ virtual const ByteString& getE() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+ virtual bool deserialise(ByteString& serialised);
+
+protected:
+ // Public components
+ ByteString n,e;
+};
+
+#endif // !_SOFTHSM_V2_RSAPUBLICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.cpp b/SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.cpp
new file mode 100644
index 0000000..1db8f50
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ SymmetricAlgorithm.cpp
+
+ Base class for symmetric algorithm classes
+ *****************************************************************************/
+
+#include "SymmetricAlgorithm.h"
+#include <algorithm>
+#include <string.h>
+
+SymmetricAlgorithm::SymmetricAlgorithm()
+{
+ currentKey = NULL;
+ currentCipherMode = SymMode::Unknown;
+ currentPaddingMode = true;
+ currentCounterBits = 0;
+ currentTagBytes = 0;
+ currentOperation = NONE;
+ currentBufferSize = 0;
+}
+
+bool SymmetricAlgorithm::encryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& /*IV = ByteString() */, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& /*aad = ByteString()*/, size_t tagBytes /* = 0 */)
+{
+ if ((key == NULL) || (currentOperation != NONE))
+ {
+ return false;
+ }
+
+ currentKey = key;
+ currentCipherMode = mode;
+ currentPaddingMode = padding;
+ currentCounterBits = counterBits;
+ currentTagBytes = tagBytes;
+ currentOperation = ENCRYPT;
+ currentBufferSize = 0;
+
+ return true;
+}
+
+bool SymmetricAlgorithm::encryptUpdate(const ByteString& data, ByteString& /*encryptedData*/)
+{
+ if (currentOperation != ENCRYPT)
+ {
+ return false;
+ }
+
+ currentBufferSize += data.size();
+
+ return true;
+}
+
+bool SymmetricAlgorithm::encryptFinal(ByteString& /*encryptedData*/)
+{
+ if (currentOperation != ENCRYPT)
+ {
+ return false;
+ }
+
+ currentKey = NULL;
+ currentCipherMode = SymMode::Unknown;
+ currentPaddingMode = true;
+ currentCounterBits = 0;
+ currentTagBytes = 0;
+ currentOperation = NONE;
+ currentBufferSize = 0;
+
+ return true;
+}
+
+bool SymmetricAlgorithm::decryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& /*IV = ByteString() */, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& /*aad = ByteString()*/, size_t tagBytes /* = 0 */)
+{
+ if ((key == NULL) || (currentOperation != NONE))
+ {
+ return false;
+ }
+
+ currentKey = key;
+ currentCipherMode = mode;
+ currentPaddingMode = padding;
+ currentCounterBits = counterBits;
+ currentTagBytes = tagBytes;
+ currentOperation = DECRYPT;
+ currentBufferSize = 0;
+ currentAEADBuffer.wipe();
+
+ return true;
+}
+
+
+bool SymmetricAlgorithm::decryptUpdate(const ByteString& encryptedData, ByteString& /*data*/)
+{
+ if (currentOperation != DECRYPT)
+ {
+ return false;
+ }
+
+ currentBufferSize += encryptedData.size();
+ currentAEADBuffer += encryptedData;
+
+ return true;
+}
+
+bool SymmetricAlgorithm::decryptFinal(ByteString& /*data*/)
+{
+ if (currentOperation != DECRYPT)
+ {
+ return false;
+ }
+
+ currentKey = NULL;
+ currentCipherMode = SymMode::Unknown;
+ currentPaddingMode = true;
+ currentCounterBits = 0;
+ currentTagBytes = 0;
+ currentOperation = NONE;
+ currentBufferSize = 0;
+ currentAEADBuffer.wipe();
+
+ return true;
+}
+
+// Key factory
+void SymmetricAlgorithm::recycleKey(SymmetricKey* toRecycle)
+{
+ delete toRecycle;
+}
+
+bool SymmetricAlgorithm::generateKey(SymmetricKey& key, RNG* rng /* = NULL */)
+{
+ if (rng == NULL)
+ {
+ return false;
+ }
+
+ if (key.getBitLen() == 0)
+ {
+ return false;
+ }
+
+ ByteString keyBits;
+
+ if (!rng->generateRandom(keyBits, key.getBitLen()/8))
+ {
+ return false;
+ }
+
+ return key.setKeyBits(keyBits);
+}
+
+bool SymmetricAlgorithm::reconstructKey(SymmetricKey& key, const ByteString& serialisedData)
+{
+ return key.setKeyBits(serialisedData);
+}
+
+SymMode::Type SymmetricAlgorithm::getCipherMode()
+{
+ return currentCipherMode;
+}
+
+bool SymmetricAlgorithm::getPaddingMode()
+{
+ return currentPaddingMode;
+}
+
+unsigned long SymmetricAlgorithm::getBufferSize()
+{
+ return currentBufferSize;
+}
+
+size_t SymmetricAlgorithm::getTagBytes()
+{
+ return currentTagBytes;
+}
+
+bool SymmetricAlgorithm::isStreamCipher()
+{
+ switch (currentCipherMode)
+ {
+ case SymMode::CFB:
+ case SymMode::CTR:
+ case SymMode::GCM:
+ case SymMode::OFB:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool SymmetricAlgorithm::isBlockCipher()
+{
+ switch (currentCipherMode)
+ {
+ case SymMode::CBC:
+ case SymMode::ECB:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
diff --git a/SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.h b/SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.h
new file mode 100644
index 0000000..7e060c4
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/SymmetricAlgorithm.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ SymmetricAlgorithm.h
+
+ Base class for symmetric algorithm classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_SYMMETRICALGORITHM_H
+#define _SOFTHSM_V2_SYMMETRICALGORITHM_H
+
+#include <string>
+#include "config.h"
+#include "SymmetricKey.h"
+#include "RNG.h"
+
+struct SymAlgo
+{
+ enum Type
+ {
+ Unknown,
+ AES,
+ DES,
+ DES3
+ };
+};
+
+struct SymMode
+{
+ enum Type
+ {
+ Unknown,
+ CBC,
+ CFB,
+ CTR,
+ ECB,
+ GCM,
+ OFB
+ };
+};
+
+struct SymWrap
+{
+ enum Type
+ {
+ Unknown,
+ AES_KEYWRAP,
+ AES_KEYWRAP_PAD
+ };
+};
+
+class SymmetricAlgorithm
+{
+public:
+ // Base constructors
+ SymmetricAlgorithm();
+
+ // Destructor
+ virtual ~SymmetricAlgorithm() { }
+
+ // Encryption functions
+ virtual bool encryptInit(const SymmetricKey* key, const SymMode::Type mode = SymMode::CBC, const ByteString& IV = ByteString(), bool padding = true, size_t counterBits = 0, const ByteString& aad = ByteString(), size_t tagBytes = 0);
+ virtual bool encryptUpdate(const ByteString& data, ByteString& encryptedData);
+ virtual bool encryptFinal(ByteString& encryptedData);
+
+ // Decryption functions
+ virtual bool decryptInit(const SymmetricKey* key, const SymMode::Type mode = SymMode::CBC, const ByteString& IV = ByteString(), bool padding = true, size_t counterBits = 0, const ByteString& aad = ByteString(), size_t tagBytes = 0);
+ virtual bool decryptUpdate(const ByteString& encryptedData, ByteString& data);
+ virtual bool decryptFinal(ByteString& data);
+
+ // Wrap/Unwrap keys
+ virtual bool wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out) = 0;
+
+ virtual bool unwrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out) = 0;
+
+ // Key factory
+ virtual void recycleKey(SymmetricKey* toRecycle);
+ virtual bool generateKey(SymmetricKey& key, RNG* rng = NULL);
+ virtual bool reconstructKey(SymmetricKey& key, const ByteString& serialisedData);
+
+ // Return cipher information
+ virtual size_t getBlockSize() const = 0;
+ virtual SymMode::Type getCipherMode();
+ virtual bool getPaddingMode();
+ virtual unsigned long getBufferSize();
+ virtual size_t getTagBytes();
+ virtual bool isStreamCipher();
+ virtual bool isBlockCipher();
+ virtual bool checkMaximumBytes(unsigned long bytes) = 0;
+
+protected:
+ // The current key
+ const SymmetricKey* currentKey;
+
+ // The current cipher mode
+ SymMode::Type currentCipherMode;
+
+ // The current padding
+ bool currentPaddingMode;
+
+ // The current counter bits
+ size_t currentCounterBits;
+
+ // The current tag bytes
+ size_t currentTagBytes;
+
+ // The current operation
+ enum
+ {
+ NONE,
+ ENCRYPT,
+ DECRYPT
+ }
+ currentOperation;
+
+ // The current number of bytes in buffer
+ unsigned long currentBufferSize;
+
+ // The current AEAD buffer
+ ByteString currentAEADBuffer;
+};
+
+#endif // !_SOFTHSM_V2_SYMMETRICALGORITHM_H
+
diff --git a/SoftHSMv2/src/lib/crypto/SymmetricKey.cpp b/SoftHSMv2/src/lib/crypto/SymmetricKey.cpp
new file mode 100644
index 0000000..550a144
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/SymmetricKey.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ SymmetricKey.cpp
+
+ Base class for symmetric key classes
+ *****************************************************************************/
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+#include "SymmetricKey.h"
+#include "CryptoFactory.h"
+
+// Base constructors
+SymmetricKey::SymmetricKey(size_t inBitLen /* = 0 */)
+{
+ bitLen = inBitLen;
+}
+
+SymmetricKey::SymmetricKey(const SymmetricKey& in)
+{
+ keyData = in.keyData;
+ bitLen = in.bitLen;
+}
+
+// Set the key
+bool SymmetricKey::setKeyBits(const ByteString& keybits)
+{
+ if ((bitLen > 0) && ((keybits.size() * 8) != bitLen))
+ {
+ return false;
+ }
+
+ keyData = keybits;
+
+ return true;
+}
+
+// Get the key
+const ByteString& SymmetricKey::getKeyBits() const
+{
+ return keyData;
+}
+
+// Get the key check value
+ByteString SymmetricKey::getKeyCheckValue() const
+{
+ ByteString digest;
+
+ HashAlgorithm* hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA1);
+ if (hash == NULL) return digest;
+
+ if (!hash->hashInit() ||
+ !hash->hashUpdate(keyData) ||
+ !hash->hashFinal(digest))
+ {
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ return digest;
+ }
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ digest.resize(3);
+
+ return digest;
+}
+
+// Serialisation
+ByteString SymmetricKey::serialise() const
+{
+ return keyData;
+}
+
+// Set the bit length
+void SymmetricKey::setBitLen(const size_t inBitLen)
+{
+ bitLen = inBitLen;
+}
+
+// Retrieve the bit length
+size_t SymmetricKey::getBitLen() const
+{
+ return bitLen;
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/SymmetricKey.h b/SoftHSMv2/src/lib/crypto/SymmetricKey.h
new file mode 100644
index 0000000..593040b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/SymmetricKey.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ SymmetricKey.h
+
+ Base class for symmetric key classes
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_SYMMETRICKEY_H
+#define _SOFTHSM_V2_SYMMETRICKEY_H
+
+#include "config.h"
+#include "ByteString.h"
+#include "Serialisable.h"
+
+class SymmetricKey : public Serialisable
+{
+public:
+ // Base constructors
+ SymmetricKey(size_t inBitLen = 0);
+
+ SymmetricKey(const SymmetricKey& in);
+
+ // Destructor
+ virtual ~SymmetricKey() { }
+
+ // Set the key
+ virtual bool setKeyBits(const ByteString& keybits);
+
+ // Get the key
+ virtual const ByteString& getKeyBits() const;
+
+ // Get the key check value
+ virtual ByteString getKeyCheckValue() const;
+
+ // Serialisation
+ virtual ByteString serialise() const;
+
+ // Set the bit length
+ virtual void setBitLen(const size_t inBitLen);
+
+ // Retrieve the bit length
+ virtual size_t getBitLen() const;
+
+protected:
+ // The key
+ ByteString keyData;
+
+ // The key length in bits
+ size_t bitLen;
+};
+
+#endif // !_SOFTHSM_V2_SYMMETRICKEY_H
+
diff --git a/SoftHSMv2/src/lib/crypto/odd.h b/SoftHSMv2/src/lib/crypto/odd.h
new file mode 100644
index 0000000..0ab2997
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/odd.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ odd.h
+
+ Odd parity table
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ODD_H
+#define _SOFTHSM_V2_ODD_H
+
+const unsigned char odd_parity[256] = {
+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
+ 0x08, 0x08, 0x0B, 0x0B, 0x0D, 0x0D, 0x0E, 0x0E,
+ 0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
+ 0x19, 0x19, 0x1A, 0x1A, 0x1C, 0x1C, 0x1F, 0x1F,
+ 0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
+ 0x29, 0x29, 0x2A, 0x2A, 0x2C, 0x2C, 0x2F, 0x2F,
+ 0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
+ 0x38, 0x38, 0x3B, 0x3B, 0x3D, 0x3D, 0x3E, 0x3E,
+ 0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
+ 0x49, 0x49, 0x4A, 0x4A, 0x4C, 0x4C, 0x4F, 0x4F,
+ 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
+ 0x58, 0x58, 0x5B, 0x5B, 0x5D, 0x5D, 0x5E, 0x5E,
+ 0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
+ 0x68, 0x68, 0x6B, 0x6B, 0x6D, 0x6D, 0x6E, 0x6E,
+ 0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
+ 0x79, 0x79, 0x7A, 0x7A, 0x7C, 0x7C, 0x7F, 0x7F,
+ 0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86,
+ 0x89, 0x89, 0x8A, 0x8A, 0x8C, 0x8C, 0x8F, 0x8F,
+ 0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97,
+ 0x98, 0x98, 0x9B, 0x9B, 0x9D, 0x9D, 0x9E, 0x9E,
+ 0xA1, 0xA1, 0xA2, 0xA2, 0xA4, 0xA4, 0xA7, 0xA7,
+ 0xA8, 0xA8, 0xAB, 0xAB, 0xAD, 0xAD, 0xAE, 0xAE,
+ 0xB0, 0xB0, 0xB3, 0xB3, 0xB5, 0xB5, 0xB6, 0xB6,
+ 0xB9, 0xB9, 0xBA, 0xBA, 0xBC, 0xBC, 0xBF, 0xBF,
+ 0xC1, 0xC1, 0xC2, 0xC2, 0xC4, 0xC4, 0xC7, 0xC7,
+ 0xC8, 0xC8, 0xCB, 0xCB, 0xCD, 0xCD, 0xCE, 0xCE,
+ 0xD0, 0xD0, 0xD3, 0xD3, 0xD5, 0xD5, 0xD6, 0xD6,
+ 0xD9, 0xD9, 0xDA, 0xDA, 0xDC, 0xDC, 0xDF, 0xDF,
+ 0xE0, 0xE0, 0xE3, 0xE3, 0xE5, 0xE5, 0xE6, 0xE6,
+ 0xE9, 0xE9, 0xEA, 0xEA, 0xEC, 0xEC, 0xEF, 0xEF,
+ 0xF1, 0xF1, 0xF2, 0xF2, 0xF4, 0xF4, 0xF7, 0xF7,
+ 0xF8, 0xF8, 0xFB, 0xFB, 0xFD, 0xFD, 0xFE, 0xFE
+};
+
+#endif // !_SOFTHSM_V2_ODD_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/AESTests.cpp b/SoftHSMv2/src/lib/crypto/test/AESTests.cpp
new file mode 100644
index 0000000..008560f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/AESTests.cpp
@@ -0,0 +1,1182 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AESTests.cpp
+
+ Contains test cases to test the AES implementation
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "AESTests.h"
+#include "CryptoFactory.h"
+#include "AESKey.h"
+#include <stdio.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(AESTests);
+
+void AESTests::setUp()
+{
+ aes = NULL;
+
+ aes = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::AES);
+
+ // Check the return value
+ CPPUNIT_ASSERT(aes != NULL);
+}
+
+void AESTests::tearDown()
+{
+ if (aes != NULL)
+ {
+ CryptoFactory::i()->recycleSymmetricAlgorithm(aes);
+ }
+
+ fflush(stdout);
+}
+
+void AESTests::testBlockSize()
+{
+ CPPUNIT_ASSERT(aes->getBlockSize() == 16);
+}
+
+void AESTests::testCBC()
+{
+ char testKeys128[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "89436760984679018453504364534464",
+ "49587346983643545706904580436731"
+ };
+
+ char testKeys192[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101213141516171819",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "096874395874290867409857496743857632098479834634",
+ "439867439058743095864395348375043296845094854983"
+ };
+
+ char testKeys256[][65] =
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20",
+ "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F",
+ "4394398576098257436095746985679043867498572406874967416846341641",
+ "4369006859867098670492857409386741095643756930847023587048579014"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "6CAEC72F5E101C66550215ACAB6B874C62E7BD074C0A09A8EE4562EFCB4E560A3E90FA0F50391087824FC27F57618E5C",
+ "E20E3123AC64FCA5536E0A2DC48DBEBCECB3F260EFF4A0EB99D72F57EF38DED336EB9DD0B968D24C91E63974E7445A21",
+ "C7910B1634DB493998608875A4652B20C64202ED507D9DBA06F62EB20A63C32FB6C9669D42A0AC29D773E6D40A63A2AC"
+ },
+ {
+ "8F48A65BF638FEDB7E6F59BAC8C110FEBA933F106D564119B88569E758B7FB83",
+ "125E1D93DC2C43A6FAFC508DB6F9A4A9F390D102C2300F0A3617CE95027BFAA3",
+ "FACB8DEF1B476400DE9796D5058E9086ECF04C927F5C160161C7A34D8288EB3C"
+ },
+ {
+ "C810E96482F109C9A05D2B1BEBAC7966BB7784F58A5478C1A07EC0DB39F6D87B",
+ "2385391BB8F2DD97280B1FAEFACB6B5C4FE12A2274D6B967509CF18500A640D6",
+ "47549520EADA1A5D931EACCC922F88BA2E386089BF97C790FD2CD38553334AE4"
+ },
+ {
+ "A7D9EAE80224624188CAA7012140E946",
+ "6ECD5C71ECA4AB9C3B71E91721CA2043",
+ "2F77AA438E9259F268985668B00650E5"
+ }
+ },
+ {
+ {
+ "FCB2FB6BF8ED8910F023A934EB9DA550E4D5B469D75B9390F4A207E54F29412450E52E980862DC80B89F6D1D10B68AA5",
+ "7EF0F65513CFE3E0D21305E2ECCBB3554B0DE119720C5A86337E57F74795BC23ED9CB82A951DE3D00D7A0DC8997319DD",
+ "5B83BFDB6EF3AEA5191F2EE3366EDE10480E9459C0DE2994DD9C6408A377DFFF8121A38CFD1AA864559B9A435A3BDD6D"
+ },
+ {
+ "81D667193D42BF19C456F4A1F7070C047D94C7EE8136FA315F938162FDDA20C1",
+ "2EFBA2B689C0F775097F98B569A1F20004F1A75F0C53473969DBE586ABCAE04D",
+ "447326913AA4565951D987F59B48870DD9285EEFCF64B429C2220E4F3E0D9DE2"
+ },
+ {
+ "891DF30BAEA2D24408A9C788D59DBAC7A6F34311813216311E18E9ED7122DB1A",
+ "F1629B62ECDF3CDAA3DA0EBB31EE37691AF4EB2B6F9CF04A9861935B2C167D02",
+ "C7BD348D5E6696CB8BA813B96EA5C42C5C3C3629D18FC9DAF1B50A0AE4843C5B"
+ },
+ {
+ "91C44D109D46C8E8656793680D43BE94",
+ "E68D8E49A19F155B7ED7253120B0D117",
+ "FAED8666F695C85283ECF51C96DB41CE"
+ }
+ },
+ {
+ {
+ "0CCFB49FE2B7E93A556E56B2C616885FBB0515F55A4210FE2F492A4775F078655CB21691CA6A54819C2D885954809D00",
+ "2FC6C785D683FC35304DD161A21FA1B256F9FBB2817F1F3BEBCE7C1E292EC6999641AA6953C0FAB6DFC2942CABD32DFB",
+ "31FAF4E3DA19D2372666AC635FFE361E33AD7865AEF616273D8F3B471F77A0998C6A41497168A65F621D912C54A4AF28"
+ },
+ {
+ "0B3842152A6365ED14AD952ABBBAF0EED2E8F36250DD25DDA301490FDE05219B",
+ "696BF21A887A04E194DCC18719E1BD623D8BD25A0CEF5EC2E21312ACE6C81F40",
+ "A2C8E61471EC80FE39AC0D8F720FEA8F2D23D04596A751C755E51CD357BCA5E0"
+ },
+ {
+ "5E0EA3AFBE191A16854C7960F087958F577EA4F80160F521A12D2211FAC25E16",
+ "F5475B4FD48F969123C9F7FB08C7E902CCA282F167BBAFF1A7C7EDDB7BCBAC76",
+ "380CB860EC6DEF4F9329F4BE826DE1FE61A71629DD978F00BEFB349ACBD0BAD8"
+ },
+ {
+ "BA1452E755E6A43E43B10DD2C1530093",
+ "07CA52926D4E8F2F6055E6E0251CB9E5",
+ "AB99E5FEE195B4433667AD3074A9322E"
+ }
+ },
+ {
+ {
+ "D2D46E577723B30E6B5FC96DC18B2C55E0EACCB07CE07C7F30FD113A987E2A2059AB7DF8985C1AE525EFAD9CE111893C",
+ "CC5B220688AC0231DBC03C8886C0D0109840B9E58FBB1A6B6C261ED9E7979E951818033A25778FF328786D1777790078",
+ "4B4A0B3D6D4E770BECC574BF66CD401942DC4D0DCD0EC65F99B2925B688BB217FCB5C946BE986C440C93279F4670CD43"
+ },
+ {
+ "29C76D62D3C4F7FECCBFD7A73B06E2ECA7AA3B2D4BE79EC945B0B88C813264D8",
+ "B898DCE11F3D6BB2182208E0BBBA7F404FE415D4D6D0772960E7CE3549B9899C",
+ "11E9552009836B51F241E972D680A9F397260163D9D5369BFC1B136FB4206966"
+ },
+ {
+ "539FC6EDAE21EDDC1CC4650367F527467916A6990E540146238AA9CD6B3B4ADE",
+ "2D9DE2BC47DAFCF7867134110C541EBCD72D67B1B23DEF6805DBFF4A4D90EF91",
+ "BF484690835FF61C4A7873A996EEB91F553978A40360E192273D3923E04DFE1E"
+ },
+ {
+ "4910EFFFBF571C98D51802F04A42213E",
+ "EDD1880FC4D41293BC74B98AF3D8A010",
+ "F8BCC258A6CD7FAA4EDF16A3CF5573C4"
+ }
+ },
+ {
+ {
+ "C2061BD0B4274B5CB4E408B492991F4195FDBFCDED1BC57442151B182BA6E8075AAF858F357C262E0034B9B5F839D823",
+ "6EEFEBCC9F8C607D21A158E23980EFA6EC234DC6EA668A446F467F4AE87521F18DC1800D87A5EBC63C444F810557B61D",
+ "00C952BA54614A1F11B0D59F3F469A859F62CCE0D35073B91B461302A7F37BD0B23401482DFCEE66ABD12C05615C9862"
+ },
+ {
+ "B36553D93EEF04AE247DBCBDDB8C039FFAC8AC1B0EF14C2E4BA653F089924451",
+ "90670C9DE58F95431591FA2BE8EA1B4B3F5BDBFC0B5199F94A41E4FC7B6B1645",
+ "A065415413D3A08E4B42A3F2681B8D122167A1E3F92D38C305761D9BF80131F1"
+ },
+ {
+ "12A758F161543F2842138B8C2453C3A05A90BE9F92CB3DD10C40AB9D1D746B49",
+ "DF1F4DDFFE1032C812FC6F35AB2B3A7B0E8D26DA49DEC8F5E08D108DB1283BEA",
+ "FDCB66159E1B5CF1BE9F7271EF2C35D5E9F7485E32D16C6AC865E64619DB8724"
+ },
+ {
+ "1FC224DCB64848B5E8F9FB91C542991F",
+ "1F8C5F65F9205098B47E26894B9154D9",
+ "19763CAC206EDFDEBEDAD9C274DEE1C1"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "69836472094875029486750948672066",
+ "48670943876904867104398574908554"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+ ByteString keyData128(testKeys128[i]);
+ ByteString keyData192(testKeys192[i]);
+ ByteString keyData256(testKeys256[i]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+ // Test 128-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void AESTests::testECB()
+{
+ char testKeys128[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "89436760984679018453504364534464",
+ "49587346983643545706904580436731"
+ };
+
+ char testKeys192[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101213141516171819",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "096874395874290867409857496743857632098479834634",
+ "439867439058743095864395348375043296845094854983"
+ };
+
+ char testKeys256[][65] =
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20",
+ "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F",
+ "4394398576098257436095746985679043867498572406874967416846341641",
+ "4369006859867098670492857409386741095643756930847023587048579014"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "6CAEC72F5E101C66550215ACAB6B874CD26479922B98D9839D7DA729B557ABA00143DB63EE66B0CDFF9F69917680151E",
+ "E20E3123AC64FCA5536E0A2DC48DBEBC0E4E53BDA45FFC97C677951A891A6B7502BB292527E726FD51EB29894D6F0AAD",
+ "C7910B1634DB493998608875A4652B205750B3B761DA7718E120C23A575F7D821F788FE6D86C317549697FBF0C07FA43"
+ },
+ {
+ "8F48A65BF638FEDB7E6F59BAC8C110FE0E5E6370CBEFACFA0D7A5744030A481B",
+ "125E1D93DC2C43A6FAFC508DB6F9A4A933738D14C219340D5F4D7203DEDCA7E1",
+ "FACB8DEF1B476400DE9796D5058E90863A9A8C8BB2420B9A85BA3E8F87BB48F2"
+ },
+ {
+ "C810E96482F109C9A05D2B1BEBAC79660143DB63EE66B0CDFF9F69917680151E",
+ "2385391BB8F2DD97280B1FAEFACB6B5C02BB292527E726FD51EB29894D6F0AAD",
+ "47549520EADA1A5D931EACCC922F88BA1F788FE6D86C317549697FBF0C07FA43"
+ },
+ {
+ "A7D9EAE80224624188CAA7012140E946",
+ "6ECD5C71ECA4AB9C3B71E91721CA2043",
+ "2F77AA438E9259F268985668B00650E5"
+ }
+ },
+ {
+ {
+ "8947CE273536C8A4D1E878F38371B9A8D2B3B45496779386CBA32CA70001D6AA6CC00A66D2AD83FFD76E9A2BCAD89A01",
+ "B151340CFECADA3AE176637D0A78686E2063E1A602C85D03AE648BDF4FA57C36F7F1878D088644BD5FB43D3C0FE1C30C",
+ "C19AE024C8F6B8E3383F675DF463512E273AAD7D0B88F22D5225EF09D2E37118D45D7C5AA26BCA9D6B1D5DDBF68F9EF6"
+ },
+ {
+ "16C30BBAE7CDB2EE1E02275B79A064F6EE69FB37C8E039400435782F550CF86A",
+ "F6C869D28D2D167C50BEE8F605D33021CB9173567B8B4AB3EEC68F0298324B78",
+ "07DB563F7E31F1E670A02F97E8D120C7EE3FCEBBF2FDC2D37FC17D93ED1A778B"
+ },
+ {
+ "52902B599686234833C4D420A9BF17FF6CC00A66D2AD83FFD76E9A2BCAD89A01",
+ "B17FA9EA89D5578A844B3D82891330B1F7F1878D088644BD5FB43D3C0FE1C30C",
+ "74BC55BE85291E0D1FA4A4444051CF65D45D7C5AA26BCA9D6B1D5DDBF68F9EF6"
+ },
+ {
+ "3F00CAAC6FA432A7C1826CA4DA7C55D6",
+ "9C2DBF449FF2C4AC1CFD7C43D200D33A",
+ "E2183AB600A986806D86ADA4EE38E562"
+ }
+ },
+ {
+ {
+ "23741EF993CBA04E5C67B42A16CA4D100BA6DF745E6D90818500DEC1CFC9811DBD3ACBFC853ED5DE825266C3B1883EC4",
+ "F14D0EB7DFDB9B8960B0E47D7F4828E8756C38BA83655AAC466986ECB229A66FA390265A4BF5F50A8DFFAD253701E418",
+ "0AAE579A796C94AF4FFB9D7C71381CB5E68E15465F30D7085A72D0CCEC7030BBC9CB7B3859E1A550BCBF11B624022C56"
+ },
+ {
+ "AFCD6801459845C88548CC337BDD4D8B87E81D9D6AC945E14E3C4E0AC976A4B9",
+ "117129A4775FC84E703F2F2C54B1B55DC4A79241F6CB0A37A8D551D71983D944",
+ "1128250DA7C9A1BBE6A61AC01F28D4D9E3027C3625BD5514AE5DFE4B9132DAFA"
+ },
+ {
+ "B275BDAF14AE286643C533258343F822BD3ACBFC853ED5DE825266C3B1883EC4",
+ "93ACFCCFE2C4736B6492A673A59DACE2A390265A4BF5F50A8DFFAD253701E418",
+ "2C2165E6491662A855FD7A20CDFF23BDC9CB7B3859E1A550BCBF11B624022C56"
+ },
+ {
+ "30BBF52D760BAEA653FD03E5E84E583A",
+ "F5F55DF3FC4D9CF2A2829BACA774A51A",
+ "7EE196D148C11FA4998A90C6C7932395"
+ }
+ },
+ {
+ {
+ "44C2B3344B002BB7A6994E1C74CC7BA70CE55BF44FD96506B553F0EFD3FE02B28329D59D480B0C1714A0DC60EB9FA8CE",
+ "568C7627FD2519BE6031F052DE8F680860F7680460E92A524EA912174BE17B1337D593DEF15FB5BA64F03D1AAE276775",
+ "99E36C0097BCFE41945C064EFA476FF4AA6048F909BEDE32A649F1035A2FB83CD601D09C3FDB36BC61B8CDE5BDD73804"
+ },
+ {
+ "D748E8E93D29775BD8831E3BC1E1ABF75F484C7CC693521A66A5AB1637822E40",
+ "010103778E123E5140F8D0356DA831E1587DB7E416AE9FAD14C6E2F78DC83148",
+ "A8B8926E8FB762A1AB8CD9FA08507D77872C8EAAAFF3527572F49497B8B366C9"
+ },
+ {
+ "CFF3212C7E94C2DD65EC1CDC998D6C4B8329D59D480B0C1714A0DC60EB9FA8CE",
+ "324D16FEEC9DCA75A80F4B80175F8A7537D593DEF15FB5BA64F03D1AAE276775",
+ "850567F4F0200CFBF88F1A6D35CAF6D9D601D09C3FDB36BC61B8CDE5BDD73804"
+ },
+ {
+ "417F142D7609AE701B3D263FFECE4502",
+ "E0DC994D8DC01C4EB2ECD19AD120C3D1",
+ "FB26CC4E48B40EAB755FF65164EFB406"
+ }
+ },
+ {
+ {
+ "048AEE75741BC60D01B512A53FEE97238F294743E7A351FAF589DD9E040BB8AF0F59D8F60E9C700F10025B5E69828819",
+ "67FB10E52640B1E060F3D7868524721AC375DC76628B0D79C5F40ADC653FC001B50C33356548289D3E70EB7FBC0E2B56",
+ "31953FF249D7519D3C39FB21D70A41033286A320193CC938C5ACBBCA2B25340829799212E3CABACE0BFD4424427705AB"
+ },
+ {
+ "8D8D50FA4619F0E1B821DCA4ACBDFD46AE92D76A0B95A0331D61C4A7032D9705",
+ "10685E8F632AC41D92E3A0403BB20C79868BD6F94691226EC54D7220C45E7233",
+ "C5FF99FD1BC2BFDBEA62894B279DE6CBF51CCD00362A557DB9D9102DAF623A50"
+ },
+ {
+ "0330B8FF58E4E6E956B4F81F7A4770200F59D8F60E9C700F10025B5E69828819",
+ "C79BABE5B34B305B05E38013DC5568F7B50C33356548289D3E70EB7FBC0E2B56",
+ "98BEE460FF803288C898A900DD08CE2529799212E3CABACE0BFD4424427705AB"
+ },
+ {
+ "9A4FD3A26DD0D3A12F224E5E7A06EB76",
+ "B86FE6F088C3A6497F21BCB29DB703D1",
+ "313CC604B301DACA48CDB6F405AA7938"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "69836472094875029486750948672066",
+ "48670943876904867104398574908554"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+ ByteString keyData128(testKeys128[i]);
+ ByteString keyData192(testKeys192[i]);
+ ByteString keyData256(testKeys256[i]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+ // Test 128-bit key
+
+ // Get the reference for the encrypted data
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void AESTests::testCTR()
+{
+ // Test vectors from RFC3686
+
+ char testKeys128[][33] =
+ {
+ "AE6852F8121067CC4BF7A5765577F39E",
+ "7E24067817FAE0D743D6CE1F32539163",
+ "7691BE035E5020A8AC6E618529F9A0DC"
+ };
+
+ char testKeys192[][49] =
+ {
+ "16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515",
+ "7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A",
+ "02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE"
+ };
+
+ char testKeys256[][65] =
+ {
+ "776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104",
+ "F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884",
+ "FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D"
+ };
+
+ char testData[][256] =
+ {
+ "53696E676C6520626C6F636B206D7367",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223"
+ };
+
+ char testResult[3][3][256] =
+ {
+ {
+ "E4095D4FB7A7B3792D6175A3261311B8",
+ "4B55384FE259C9C84E7935A003CBE928",
+ "145AD01DBF824EC7560863DC71E3E0C0"
+ },
+ {
+ "5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28",
+ "453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00",
+ "F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C"
+ },
+ {
+ "C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F",
+ "96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935",
+ "EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8"
+ }
+ };
+
+ char testCB[3][3][33] =
+ {
+ {
+ "00000030000000000000000000000001",
+ "0000004836733C147D6D93CB00000001",
+ "00000060DB5672C97AA8F0B200000001"
+ },
+ {
+ "006CB6DBC0543B59DA48D90B00000001",
+ "0096B03B020C6EADC2CB500D00000001",
+ "00FAAC24C1585EF15A43D87500000001"
+ },
+ {
+ "00E0017B27777F3F4A1786F000000001",
+ "0007BDFD5CBD60278DCC091200000001",
+ "001CC5B751A51D70A1C1114800000001"
+ }
+ };
+
+ for (int i = 0; i < 3; i++)
+ {
+ ByteString keyData128(testKeys128[i]);
+ ByteString keyData192(testKeys192[i]);
+ ByteString keyData256(testKeys256[i]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+
+ ByteString plainText(testData[i]), shsmPlainText;
+ ByteString CB;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+ // Test 128-bit key
+ CB = ByteString(testCB[i][0]);
+ cipherText = ByteString(testResult[i][0]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ CB = ByteString(testCB[i][1]);
+ cipherText = ByteString(testResult[i][1]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ CB = ByteString(testCB[i][2]);
+ cipherText = ByteString(testResult[i][2]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::CTR, CB));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+}
+
+#ifdef WITH_AES_GCM
+void AESTests::testGCM()
+{
+ // Test vectors from NIST via Botan
+
+ char test128[8][6][256] =
+ {
+ {
+ "00000000000000000000000000000000",
+ "000000000000000000000000",
+ "",
+ "",
+ "10",
+ "58E2FCCEFA7E3061367F1D57A4E7455A"
+ },
+ {
+ "00000000000000000000000000000000",
+ "000000000000000000000000",
+ "00000000000000000000000000000000",
+ "",
+ "10",
+ "0388DACE60B6A392F328C2B971B2FE78AB6E47D42CEC13BDF53A67B21257BDDF"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBADDECAF888",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B391AAFD255",
+ "",
+ "10",
+ "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBADDECAF888",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "10",
+ "42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E0915BC94FBC3221A5DB94FAE95AE7121A47"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBAD",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "10",
+ "61353B4C2806934A777FF51FA22A4755699B2A714FCDC6F83766E5F97B6C742373806900E49F24B22B097544D4896B424989B5E1EBAC0F07C23F45983612D2E79E3B0785561BE14AACA2FCCB"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "9313225DF88406E555909C5AFF5269AA6A7A9538534F7DA1E4C303D2A318A728C3C0C95156809539FCF0E2429A6B525416AEDBF5A0DE6A57A637B39B",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "10",
+ "8CE24998625615B603A033ACA13FB894BE9112A5C3A211A8BA262A3CCA7E2CA701E4A9A4FBA43C90CCDCB281D48C7C6FD62875D2ACA417034C34AEE5619CC5AEFFFE0BFA462AF43C1699D050"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "CAFEBABEFACEDBAD",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "C",
+ "61353B4C2806934A777FF51FA22A4755699B2A714FCDC6F83766E5F97B6C742373806900E49F24B22B097544D4896B424989B5E1EBAC0F07C23F45983612D2E79E3B0785561BE14A"
+ },
+ {
+ "FEFFE9928665731C6D6A8F9467308308",
+ "9313225DF88406E555909C5AFF5269AA6A7A9538534F7DA1E4C303D2A318A728C3C0C95156809539FCF0E2429A6B525416AEDBF5A0DE6A57A637B39B",
+ "D9313225F88406E5A55909C5AFF5269A86A7A9531534F7DA2E4C303D8A318A721C3C0C95956809532FCF0E2449A6B525B16AEDF5AA0DE657BA637B39",
+ "FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2",
+ "C",
+ "8CE24998625615B603A033ACA13FB894BE9112A5C3A211A8BA262A3CCA7E2CA701E4A9A4FBA43C90CCDCB281D48C7C6FD62875D2ACA417034C34AEE5619CC5AEFFFE0BFA462AF43C"
+ }
+ };
+
+ char test192[8][6][256] =
+ {
+ {
+ "000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "",
+ "",
+ "10",
+ "cd33b28ac773f74ba00ed1f312572435"
+ },
+ {
+ "000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "00000000000000000000000000000000",
+ "",
+ "10",
+ "98e7247c07f0fe411c267e4384b0f6002ff58d80033927ab8ef4d4587514f0fb"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
+ "",
+ "10",
+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade2569924a7c8587336bfb118024db8674a14"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda27102519498e80f1478f37ba55bd6d27618c"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f765dcc57fcf623a24094fcca40d3533f8"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373bdcf566ff291c25bbb8568fc3d376a6d9"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda27102519498e80f1478f37ba55bd"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f765dcc57fcf623a24094fcca4"
+ }
+ };
+
+ char test256[8][6][256] =
+ {
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "",
+ "",
+ "10",
+ "530f8afbc74536b9a963b4f1c4cb738b"
+ },
+ {
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "000000000000000000000000",
+ "00000000000000000000000000000000",
+ "",
+ "10",
+ "cea7403d4d606b6e074ec5d3baf39d18d0d1c8a799996bf0265b98b5d48ab919"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
+ "",
+ "10",
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015adb094dac5d93471bdec1a502270e3cc6c"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f66276fc6ece0f4e1768cddf8853bb2d551b"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f3a337dbf46a792c45e454913fe2ea8f2",
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "10",
+ "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3fa44a8266ee1c8eb0c8b5d4cf5ae9f19a"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbaddecaf888",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f66276fc6ece0f4e1768cddf8853"
+ },
+ {
+ "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
+ "cafebabefacedbad",
+ "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
+ "feedfacedeadbeeffeedfacedeadbeefabaddad2",
+ "C",
+ "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f3a337dbf46a792c45e454913"
+ }
+ };
+
+ for (int i = 0; i < 8; i++)
+ {
+ ByteString keyData128(test128[i][0]);
+ ByteString keyData192(test192[i][0]);
+ ByteString keyData256(test256[i][0]);
+
+ AESKey aesKey128(128);
+ CPPUNIT_ASSERT(aesKey128.setKeyBits(keyData128));
+ AESKey aesKey192(192);
+ CPPUNIT_ASSERT(aesKey192.setKeyBits(keyData192));
+ AESKey aesKey256(256);
+ CPPUNIT_ASSERT(aesKey256.setKeyBits(keyData256));
+
+ ByteString IV;
+ ByteString plainText;
+ ByteString AAD;
+ size_t tagBits;
+ ByteString cipherText;
+
+ ByteString shsmPlainText;
+ ByteString shsmCipherText;
+ ByteString OB;
+
+ // Test 128-bit key
+ IV = ByteString(test128[i][1]);
+ plainText = ByteString(test128[i][2]);
+ AAD = ByteString(test128[i][3]);
+ tagBits = ByteString(test128[i][4]).long_val();
+ cipherText = ByteString(test128[i][5]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey128, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey128, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ CPPUNIT_ASSERT(OB.size() == 0);
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 192-bit key
+ IV = ByteString(test192[i][1]);
+ plainText = ByteString(test192[i][2]);
+ AAD = ByteString(test192[i][3]);
+ tagBits = ByteString(test192[i][4]).long_val();
+ cipherText = ByteString(test192[i][5]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey192, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey192, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ CPPUNIT_ASSERT(OB.size() == 0);
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 256-bit key
+ IV = ByteString(test256[i][1]);
+ plainText = ByteString(test256[i][2]);
+ AAD = ByteString(test256[i][3]);
+ tagBits = ByteString(test256[i][4]).long_val();
+ cipherText = ByteString(test256[i][5]);
+
+ // Now, do the same thing using our AES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(aes->encryptInit(&aesKey256, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(aes->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(aes->decryptInit(&aesKey256, SymMode::GCM, IV, true, 0, AAD, tagBits));
+
+ CPPUNIT_ASSERT(aes->decryptUpdate(shsmCipherText, OB));
+ CPPUNIT_ASSERT(OB.size() == 0);
+
+ CPPUNIT_ASSERT(aes->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+}
+#endif
+
+void AESTests::testWrap(const char testKeK[][128], const char testKey[][128], const char testCt[][128], const int testCnt, SymWrap::Type mode)
+{
+ for (int i = 0; i < testCnt; i++)
+ {
+ ByteString kekData(testKeK[i]);
+ ByteString keyData(testKey[i]);
+
+ AESKey aesKeK(kekData.size() * 8);
+ CPPUNIT_ASSERT(aesKeK.setKeyBits(kekData));
+
+ ByteString wrapped;
+ ByteString expectedCt(testCt[i]);
+ CPPUNIT_ASSERT(aes->wrapKey(&aesKeK, mode, keyData, wrapped));
+ CPPUNIT_ASSERT(wrapped.size() == expectedCt.size());
+ CPPUNIT_ASSERT(wrapped == expectedCt);
+
+ ByteString unwrapped;
+ CPPUNIT_ASSERT(aes->unwrapKey(&aesKeK, mode, wrapped, unwrapped));
+ CPPUNIT_ASSERT(unwrapped.size() == keyData.size());
+ CPPUNIT_ASSERT(unwrapped == keyData);
+/*
+ #ifdef HAVE_AES_KEY_WRAP_PAD
+ keyData.resize(20);
+ ByteString padwrapped;
+ CPPUNIT_ASSERT(aes->wrapKey(&aesKeK, SymWrap::AES_KEYWRAP_PAD, keyData, padwrapped));
+ CPPUNIT_ASSERT(padwrapped.size() == 32);
+
+ ByteString padunwrapped;
+ CPPUNIT_ASSERT(aes->unwrapKey(&aesKeK, SymWrap::AES_KEYWRAP_PAD, padwrapped, padunwrapped));
+ CPPUNIT_ASSERT(padunwrapped == keyData);
+ #endif
+*/
+ }
+}
+
+// RFC 3394 tests
+void AESTests::testWrapWoPad()
+{
+ char testKeK[][128] = {
+ "000102030405060708090A0B0C0D0E0F", // section 4.1
+ "000102030405060708090A0B0C0D0E0F1011121314151617", // section 4.2
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", // section 4.3
+ "000102030405060708090A0B0C0D0E0F1011121314151617", // section 4.4
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", // section 4.5
+ "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F", // section 4.6
+ };
+ char testKey[][128] = {
+ "00112233445566778899AABBCCDDEEFF",
+ "00112233445566778899AABBCCDDEEFF",
+ "00112233445566778899AABBCCDDEEFF",
+ "00112233445566778899AABBCCDDEEFF0001020304050607",
+ "00112233445566778899AABBCCDDEEFF0001020304050607",
+ "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F"
+ };
+ char testCt[][128] = {
+ "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5",
+ "96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D",
+ "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7",
+ "031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2",
+ "A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1",
+ "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21"
+ };
+
+ testWrap(testKeK, testKey, testCt, sizeof(testKeK) / 128, SymWrap::AES_KEYWRAP);
+}
+
+// RFC 5649 tests
+void AESTests::testWrapPad()
+{
+ char testKeK[][128] = {
+ "5840DF6E29B02AF1AB493B705BF16EA1AE8338F4DCC176A8", // section 6 example 1
+ "5840DF6E29B02AF1AB493B705BF16EA1AE8338F4DCC176A8", // section 6 example 2
+ };
+ char testKey[][128] = {
+ "C37B7E6492584340BED12207808941155068F738",
+ "466F7250617369"
+ };
+ char testCt[][128] = {
+ "138BDEAA9B8FA7FC61F97742E72248EE5AE6AE5360D1AE6A5F54F373FA543B6A",
+ "AFBEB0F07DFBF5419200F2CCB50BB24F"
+ };
+
+ testWrap(testKeK, testKey, testCt, sizeof(testKeK) / 128, SymWrap::AES_KEYWRAP_PAD);
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/AESTests.h b/SoftHSMv2/src/lib/crypto/test/AESTests.h
new file mode 100644
index 0000000..3a50b11
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/AESTests.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ AESTests.h
+
+ Contains test cases to test the AES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_AESTESTS_H
+#define _SOFTHSM_V2_AESTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "SymmetricAlgorithm.h"
+
+class AESTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(AESTests);
+ CPPUNIT_TEST(testBlockSize);
+ CPPUNIT_TEST(testCBC);
+ CPPUNIT_TEST(testECB);
+ CPPUNIT_TEST(testCTR);
+#ifdef WITH_AES_GCM
+ CPPUNIT_TEST(testGCM);
+#endif
+#ifdef HAVE_AES_KEY_WRAP
+ CPPUNIT_TEST(testWrapWoPad);
+#endif
+#ifdef HAVE_AES_KEY_WRAP_PAD
+ CPPUNIT_TEST(testWrapPad);
+#endif
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testBlockSize();
+ void testCBC();
+ void testECB();
+ void testCTR();
+#ifdef WITH_AES_GCM
+ void testGCM();
+#endif
+ void testWrapWoPad();
+ void testWrapPad();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // AES instance
+ SymmetricAlgorithm* aes;
+ void testWrap(const char testKeK[][128], const char testKey[][128], const char testCt[][128], const int testCnt, SymWrap::Type mode);
+};
+
+#endif // !_SOFTHSM_V2_AESTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DESTests.cpp b/SoftHSMv2/src/lib/crypto/test/DESTests.cpp
new file mode 100644
index 0000000..bcb1c6b
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DESTests.cpp
@@ -0,0 +1,1164 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DESTests.cpp
+
+ Contains test cases to test the DES implementation
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "DESTests.h"
+#include "CryptoFactory.h"
+#include "DESKey.h"
+#include <stdio.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DESTests);
+
+void DESTests::setUp()
+{
+ des = NULL;
+
+ des = CryptoFactory::i()->getSymmetricAlgorithm(SymAlgo::DES);
+
+ // Check the return value
+ CPPUNIT_ASSERT(des != NULL);
+}
+
+void DESTests::tearDown()
+{
+ if (des != NULL)
+ {
+ CryptoFactory::i()->recycleSymmetricAlgorithm(des);
+ }
+
+ fflush(stdout);
+}
+
+void DESTests::testBlockSize()
+{
+ CPPUNIT_ASSERT(des->getBlockSize() == 8);
+}
+
+void DESTests::testCBC()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "ACC8B1BE444EEA9E016A46EF600E9B3FB2C87DE8CE9BE5394917AABB0A04639A3BFF1E250FE971D7",
+ "ACC8B1BE444EEA9E016A46EF600E9B3FB2C87DE8CE9BE5394917AABB0A04639A3BFF1E250FE971D7",
+ "ACC8B1BE444EEA9E016A46EF600E9B3FB2C87DE8CE9BE5394917AABB0A04639A3BFF1E250FE971D7"
+ },
+ {
+ "F9A1913AA27A05379506BE00D5F7398F67722076A3439E759BA729A58E8FEE64",
+ "F9A1913AA27A05379506BE00D5F7398F67722076A3439E759BA729A58E8FEE64",
+ "F9A1913AA27A05379506BE00D5F7398F67722076A3439E759BA729A58E8FEE64"
+ },
+ {
+ "36FD5581BB31F3E27910895DC2F2599CD0F8B8F002220588",
+ "36FD5581BB31F3E27910895DC2F2599CD0F8B8F002220588",
+ "36FD5581BB31F3E27910895DC2F2599CD0F8B8F002220588"
+ },
+ {
+ "B81DA29972385E55CB453A17B6D88D22",
+ "B81DA29972385E55CB453A17B6D88D22",
+ "B81DA29972385E55CB453A17B6D88D22"
+ }
+ },
+ {
+ {
+ "EE16FFE3CC4D4589766FA0957FB728A75D44A00D9BEBE2D43C4D4F3A5AFDB49730CFD4DF46D3AEF6",
+ "A070EE9DED89EE198E0E9B3CEB4879BB0244AB7FCD3450ED044BB5EE0AC8F7797383FDB8AAEF77B8",
+ "E7C594590C9CA00B376B702CE3B92C3F699B3EEEB2CEA08FA551350C837BF031FCAF4E1E97450327"
+ },
+ {
+ "D4142C47C700069F3E71EA6B1EF301B9B97261543ED75B32242C05A253B077B8",
+ "102BBE7D93CD0EF66280D3FA1F2A3976FB9C4D1B155D19E4985ADB86015DDE8C",
+ "600C3A75AC6EB4C4609BA6B7ED273ED56E59CD49FC911C33DD8DFCA384BAA462"
+ },
+ {
+ "47452120CD84CC32FC72F3B8600E5C43EEE192A29BC6BCB7",
+ "ADCF4292A32E51A7843CC8590E6934083A2CC847082FF2B4",
+ "D0FA596AC00BDA870999FD3FA2494C3C8B40B261EB3066F6"
+ },
+ {
+ "6BD20CDBE6E6ECAD6ED829FB43E92751",
+ "AE4379E371E295F63423F861B59111F0",
+ "2757FC58EDEEB8499EA9B49AB2729BAD"
+ }
+ },
+ {
+ {
+ "298621D5237F6230067DE7871DDBA6991E85CA14AD661D21357240923604D23A6A4119277B75B331",
+ "2C9F4FC0ACE7C8A4847472A0D5DDD42F36D3B2C46144B5A0ECDBB59806472E6257952DFD4DB9EBE5",
+ "679A832C630207E76BC1FF8371C61CA2518E37FE97EDED1B171E3E11807250145736949368AC822B"
+ },
+ {
+ "80FFD37B545675BB8C7CD317A73AB48CC0A39D3D9C11474EC3FD1220A066C034",
+ "F9228036718792EE86A85626AB1BC05E17F9CE21FF5D1723D0442CE852F004C3",
+ "D5F5F1EA7D8C2038FEDCBEDF157A5D2469A941FEC696D74DB8359CA5AECDD4CE"
+ },
+ {
+ "1ABB1CC10F589D993030A978B1B7F44AD52FFFEBF23638CA",
+ "D2423F54FA4978C95E4B13EF4DD6AA82DFD772F0FDAF5AD1",
+ "8128EC49D71F5711E5304E7C4423C63AD0EFC45453B66583"
+ },
+ {
+ "B9EE976AB97396047510C1DEA5C86A4B",
+ "46BA1930042146B31BD8FAF3AE6F3414",
+ "46EF3BCCA73E33C03D81BFE0DFFA7ABD"
+ }
+ },
+ {
+ {
+ "30D1B2556D516F20C2FD117FE0355845FBB0B11ABE5922A7EAA19C3A48E30207218321B3F0F30A6D",
+ "CBFA560297901DD691CDFDF98675BD7FF3A64FDCC0EF02F29C81105D3ECAC4E2803E2279F4476B35",
+ "4A30EC10433BE3695DC2B064E6240419C7BF81F1EE7640D5E2FFFA106666A2CEBF18DB954A992B5E"
+ },
+ {
+ "61FFB2E5A73170603E48F9823E6DF7105C9A909CC2F5CEDBEA7E60C076355B37",
+ "8408BD722B12031D17A1645AA59B05E2A50F7002B19877D6EB1C9BB7107C523F",
+ "97EF5791017B10CF07FB8144C19633522CBBE55DC63EF608F8734EE6484C0B0E"
+ },
+ {
+ "7205DC463B3D5EC858C8E7A13844A1A8FF21C0D615CA56AF",
+ "D5D08C1DC728A47CD55A2ACBB811294962022E745F4BCDF4",
+ "7761189D73039A3F06BDDF00B308D7A43BE7BEA1CE9D042E"
+ },
+ {
+ "1702428661BA4CFE686CFDEDFFAA6A27",
+ "9218A89B0A7AEC7E6E2AF1CA493B2829",
+ "6EEB9F7DDF66CED3DB74F7E8DE0CB2CD"
+ }
+ },
+ {
+ {
+ "4FD3A4C759827F6E188E542B83A858026C17FD1DEF21477A964D122B62EE55FA9DB3CCF05A768C83",
+ "F2C8B52652970805EE60ECECC8369C98443463F1C3A5A6357DFDFEE6B7F1EF0CF05523B5469E4555",
+ "21FCBDC92C07F112D19742F5100F2A995E27CB282D73DF5CFEC802C629A279BD4E498C98D170003E"
+ },
+ {
+ "3FD4C32A44DC0A9605A5A793C57E94826E80FC9E8E9620BBC2E02FE41A62A2D3",
+ "4FC88F1E88C3B5A76CF6BE5FA8205BA6F7FA201F7C40E8F0F9CA156E140A4EC5",
+ "CCE31260C967F4B9BB3D2D31F82320715E434C1313D911C58CE7E42AA78DA831"
+ },
+ {
+ "714766BE5CB60DA99DC0BD4E7E655ADE7F26E45F372EF1BF",
+ "00064542E2B4821B4E9173DA6FD1ABAE45C5E5CF26DB506D",
+ "4D88D531C20E63A39372F275329BDBEBE15E7D2C32F2A98F"
+ },
+ {
+ "4933917C9B56124914D2B76DE221BA13",
+ "7F2D1CA9D942630FE1E954E4176E84A5",
+ "9A46902F3997F0EB121981DAEC6D89C4"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::CBC, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void DESTests::testECB()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "ACC8B1BE444EEA9E44404B8595B7667982F1BDF99F419F083249964334F2B15F7E422822773666C0",
+ "ACC8B1BE444EEA9E44404B8595B7667982F1BDF99F419F083249964334F2B15F7E422822773666C0",
+ "ACC8B1BE444EEA9E44404B8595B7667982F1BDF99F419F083249964334F2B15F7E422822773666C0"
+ },
+ {
+ "F9A1913AA27A0537CA0BB1A6417C4037978BC92CEFCD10BB7E422822773666C0",
+ "F9A1913AA27A0537CA0BB1A6417C4037978BC92CEFCD10BB7E422822773666C0",
+ "F9A1913AA27A0537CA0BB1A6417C4037978BC92CEFCD10BB7E422822773666C0"
+ },
+ {
+ "36FD5581BB31F3E2ADA81678B64A0F3C7E422822773666C0",
+ "36FD5581BB31F3E2ADA81678B64A0F3C7E422822773666C0",
+ "36FD5581BB31F3E2ADA81678B64A0F3C7E422822773666C0"
+ },
+ {
+ "B81DA29972385E55EA1F3677CDC02D27",
+ "B81DA29972385E55EA1F3677CDC02D27",
+ "B81DA29972385E55EA1F3677CDC02D27"
+ }
+ },
+ {
+ {
+ "278B2CA6259C30E180CCB62E69F0841F235507E2FB3404FC2BC223E37E32B3A78207EA5D3E19A5FD",
+ "417579E3ABEF6F0D620B4FF88E2220457466420803140BFEFBA062A2A41D7C15061019377C6BFD8A",
+ "A676D0404F0F105B2073B9DD19C8C434428098BFC5AF1292FE12477340395F118F45B5BE23F16C4E"
+ },
+ {
+ "7D004390E5638E54077E2551B01BD52BFA1B98403ECE1AEF8207EA5D3E19A5FD",
+ "391B84593FEA836450318A6E943F1C3A4A6BD74E5001EB7A061019377C6BFD8A",
+ "DEAF58111ECCCB449F0C2564B52E360E4AACC8672ABBDF1A8F45B5BE23F16C4E"
+ },
+ {
+ "A6947F9EF4159BAE636A70B904059BC38207EA5D3E19A5FD",
+ "14ADFE212E27BF7F409395B45577F2C8061019377C6BFD8A",
+ "FF87BF761FC159F4442B3B4593233BC48F45B5BE23F16C4E"
+ },
+ {
+ "3A1777DAAAC85389EE0B499A90AE1739",
+ "376E61DF2EAFE5B523964A03885AD085",
+ "E4D81EE64FE8FB187EB7B5E80E075C73"
+ }
+ },
+ {
+ {
+ "F105809DF621715F4D3492E1EEC4A7DE0775A0632ECC13429DF0DC695A60882FA47F93E855A1445B",
+ "77C85215179312315997B4D0E997DB413176C80A8ED9F5EB9B726200224CE97C20A8A19F543BCCBD",
+ "AF1477E32B5BB1CA46D26B6020B3B48DB0A90A97B1BA60F032ADA648296EC92DEE924AA617423FD1"
+ },
+ {
+ "0FB3C3D9D93E0025F87909CD351D0116C0F684A204015E2CA47F93E855A1445B",
+ "67A66DB3209C406D2FE31AF6C36D24C7B32D0F8F1EAFA90020A8A19F543BCCBD",
+ "F85B1F07D788C59CD3DE6D562A175725DF596847ADEA8764EE924AA617423FD1"
+ },
+ {
+ "243A34CD70CE3819B9510980B6EFF3EAA47F93E855A1445B",
+ "997E145467B88D9D4C923797F539AC1620A8A19F543BCCBD",
+ "836788D7AD1F879B405438775FFD6D76EE924AA617423FD1"
+ },
+ {
+ "70856D6B67EE353F27EBB96462DACE63",
+ "D02F2A92C175A58001D89C4AEC476384",
+ "4ED379A40187826CAA90D2D6A05D5A9B"
+ }
+ },
+ {
+ {
+ "C79F67ABCE6F741CF6D5B7B4870397779AEB89F48805DD1A28305E804A4A2B91114E1CF0C7FA91DA",
+ "42956EA3B9415E8FE75B667A7C6B1ADF64D08E53C38DE733A776A97C7A8FC27E32945078552FA3E2",
+ "3685365AD0F07609E13CCDE69CEDC8CCA0C37262A87B734286B9119643AC3BABE435BDA25919BE86"
+ },
+ {
+ "09B882774309CC2B117586F5FA8BF7E4A5DA2A65E137665B114E1CF0C7FA91DA",
+ "0E52A9ABE753758D3C4F6326A8F689282D1DAB8AF6FC8CFF32945078552FA3E2",
+ "8DB6B9D50B5B8CE7DA56546CFF36C16BA3159E0EB7BD649AE435BDA25919BE86"
+ },
+ {
+ "025F9704F6ACD844BCFC6EBA809CD871114E1CF0C7FA91DA",
+ "1692C6A1DF9192C6D4125991EA9A9CBE32945078552FA3E2",
+ "6B848E67225EDDCCD7E8EC89ACDAA0AFE435BDA25919BE86"
+ },
+ {
+ "9D01CD89916AEE48AFE528A376E07AE9",
+ "6FA6A689405048060D65E1B1240B76B7",
+ "7EADEB7073D2EA995C5ED613C978817F"
+ }
+ },
+ {
+ {
+ "A98D0E8E72C589D80D240F192CF65C30FF3A1AB9D8CE54B09AA249C72E395AC3B40F19A649C1B237",
+ "33AC43C7A936665859431D18C089EE45F1356C34F5DF462D81BBFA42380A7E4F6732A473091A3673",
+ "FD4F2F77CCE20147CD0932B2E2D8D5978523F6A03D59E31E1F678A5DA4C350132E94F199555C371E"
+ },
+ {
+ "39453F3BF3C0CAE54279D96F4592359A5AEE6DD04D5F6162B40F19A649C1B237",
+ "E2AFCEEFF2317C520D890D7F2CB91ACD99D5DCAEC9C409016732A473091A3673",
+ "CB19BF88B2DEDDE981E048379A47BDF77ED5F815034CB07A2E94F199555C371E"
+ },
+ {
+ "9D466BACFA69266F7CC26D2C8B8CD203B40F19A649C1B237",
+ "265FDBCCF5F2325B3C8770ABEEECA4166732A473091A3673",
+ "C61E9B86A8A663AE1566CFFCF2046D6B2E94F199555C371E"
+ },
+ {
+ "380091B24160152B63EF067F6C189385",
+ "548EB237B455CBA0100A5C52A6F28C2B",
+ "066C3B0C5E6AF1E9BDD3DDAE5040F809"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::ECB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void DESTests::testOFB()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "C59E2ADDC8D9529368469843865740390AE5DDB1B5B816204395813968496846",
+ "C59E2ADDC8D9529368469843865740390AE5DDB1B5B816204395813968496846",
+ "C59E2ADDC8D9529368469843865740390AE5DDB1B5B816204395813968496846"
+ },
+ {
+ "D83E5E8D823844AE48567490687546090EE32BBFE7E3542F",
+ "D83E5E8D823844AE48567490687546090EE32BBFE7E3542F",
+ "D83E5E8D823844AE48567490687546090EE32BBFE7E3542F"
+ },
+ {
+ "E89FCA8099D6B1FF6795867965624526",
+ "E89FCA8099D6B1FF6795867965624526",
+ "E89FCA8099D6B1FF6795867965624526"
+ },
+ {
+ "CA253BAC45D205E236",
+ "CA253BAC45D205E236",
+ "CA253BAC45D205E236"
+ }
+ },
+ {
+ {
+ "3E9FB188FC11138D05109EA396CA48E1681DF27A857C3C4A9E92D3DC85A5F313",
+ "3440BEFCF35DC87716D8440F71BAF9ACD0441E10B9E5B525F0584499620086E2",
+ "DDB35281888DF064195C42D45E4E2571AD62113A228B5107D1AC849861C199C0"
+ },
+ {
+ "233FC5D8B6F005B02500727078E84ED16C1B0474D7277E45",
+ "29E0CAACB9BCDE4A36C8A8DC9F98FF9CD442E81EEBBEF72A",
+ "C01326D1C26CE659394CAE07B06C2341A964E73470D01308"
+ },
+ {
+ "139E51D5AD1EF0E10AC3809975FF4DFE",
+ "19415EA1A2522B1B190B5A35928FFCB3",
+ "F0B2B2DCD9821308168F5CEEBD7B206E"
+ },
+ {
+ "3124A0F9711A44FC5B",
+ "3BFBAF8D7E569F0648",
+ "D20843F00586A71547"
+ }
+ },
+ {
+ {
+ "E376288A10BD52CB7162ADA9A732D24B574B1E7CB4FF5C791FFEA2E481AD3049",
+ "FD82CFAE85B8581FFCF489F467D94B1B4FAAAEDDE4EC531ABD30D7EA235896AA",
+ "24D9411BA456571900244AEA3EA7159BAA96522B6F891606A8D9A559FE218A9B"
+ },
+ {
+ "FED65CDA5A5C44F65172417A4910D47B534DE872E6A41E76",
+ "E022BBFECF594E22DCE4652789FB4D2B4BAC58D3B6B71115",
+ "3979354BEEB741242034A639D08513ABAE90A4253DD25409"
+ },
+ {
+ "CE77C8D741B2B1A77EB1B3934407D754",
+ "D0832FF3D4B7BB73F32797CE84EC4E04",
+ "09D8A146F559B4750FF754D0DD921084"
+ },
+ {
+ "ECCD39FB9DB605BA2F",
+ "F239DEDF08B30F6EA2",
+ "2B62506A295D00685E"
+ }
+ },
+ {
+ {
+ "740A4786C73A7C6B52DAF270161895E13B4437C56B9837827C2FE237532F4C19",
+ "581B63C58404AEBECFDFD51D74A79836C11514685B47F3B02A2419AF0AA8C625",
+ "D5FCB196868673D136D480E0B6EFC33C589131D87A4AC004A6E0DE8ADC8DE611"
+ },
+ {
+ "69AA33D68DDB6A5672CA1EA3F83A93D13F42C1CB39C3758D",
+ "45BB1795CEE5B883EFCF39CE9A859E06C513E266091CB1BF",
+ "C85CC5C6CC6765EC16C46C3358CDC50C5C97C7D62811820B"
+ },
+ {
+ "590BA7DB96359F075D09EC4AF52D90FE",
+ "751A8398D50B4DD2C00CCB2797929D29",
+ "F8FD51CBD78990BD39079EDA55DAC623"
+ },
+ {
+ "7BB156F74A312B1A0C",
+ "57A072B4090FF9CF91",
+ "DA47A0E70B8D24A068"
+ }
+ },
+ {
+ {
+ "0855A84EAD2176C3F10B9DCFC8D1A379AF616FC5C5CD4E6D434353C52832F9F6",
+ "A8420E97462B0215AAC1DB0835D4064C6A8B123327FC396C9520BEA70B59B412",
+ "3461DEDF1B4893E16706900E1DDBE351E90C1300B9B01E8A518A01AD56E9AC8C"
+ },
+ {
+ "15F5DC1EE7C060FED11B711C26F3A549AB6799CB97960C62",
+ "B5E27AC70CCA14288AD137DBDBF6007C6E8DE43D75A77B63",
+ "29C1AA8F51A985DC47167CDDF3F9E561ED0AE50EEBEB5C85"
+ },
+ {
+ "25544813FC2E95AFFED883F52BE4A666",
+ "8543EECA1724E179A512C532D6E10353",
+ "19603E824A47708D68D58E34FEEEE64E"
+ },
+ {
+ "07EEB93F202A21B2AF",
+ "A7F91FE6CB205564F4",
+ "3BDACFAE9643C49039"
+ }
+ }
+ };
+
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::OFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
+
+void DESTests::testCFB()
+{
+#ifndef WITH_FIPS
+ char testKeys56[][17] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4698436794236871",
+ "0940278947239572"
+ };
+
+ char testKeys112[][33] =
+ {
+ "00000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F10",
+ "404142434445464748494A4B4C4D4E4F",
+ "64398647034486943598534703463870",
+ "87406984068406984607412103517413"
+ };
+#endif
+
+ char testKeys168[][49] =
+ {
+ "000000000000000000000000000000000000000000000000",
+ "0102030405060708090A0B0C0D0E0F101112131415161718",
+ "404142434445464748494A4B4C4D4E4F5051525354555657",
+ "643906874509874309687459084769847562436043696747",
+ "430135460496813044639085714376487549490586439575"
+ };
+
+ char testData[][256] =
+ {
+ "4938673409687134684698438657403986439058740935874395813968496846",
+ "549813644389670948567490687546098245665626527788",
+ "64398769586792586795867965624526",
+ "468376458463264536"
+ };
+
+ char testResult[5][4][3][256] = {
+ {
+ {
+ "C59E2ADDC8D95293F8ED346ADAF018111F0B6726349664FF9B02C46C2EC5B96F",
+ "C59E2ADDC8D95293F8ED346ADAF018111F0B6726349664FF9B02C46C2EC5B96F",
+ "C59E2ADDC8D95293F8ED346ADAF018111F0B6726349664FF9B02C46C2EC5B96F"
+ },
+ {
+ "D83E5E8D823844AE748E369586FA76A2BFD1E668EC78D67B",
+ "D83E5E8D823844AE748E369586FA76A2BFD1E668EC78D67B",
+ "D83E5E8D823844AE748E369586FA76A2BFD1E668EC78D67B"
+ },
+ {
+ "E89FCA8099D6B1FFB3A24C435B847A73",
+ "E89FCA8099D6B1FFB3A24C435B847A73",
+ "E89FCA8099D6B1FFB3A24C435B847A73"
+ },
+ {
+ "CA253BAC45D205E270",
+ "CA253BAC45D205E270",
+ "CA253BAC45D205E270"
+ }
+ },
+ {
+ {
+ "3E9FB188FC11138D49C438ABB98A3846671A4DB257AA62C7929CD55A43E46D88",
+ "3440BEFCF35DC8773DD631A9C8CCF222009D45E301BBF6432A78E99416CE87D8",
+ "DDB35281888DF06446772085E3DE849298B4BE0089979260DDC59FACB17AD0BE"
+ },
+ {
+ "233FC5D8B6F005B0966FB313EA0DDFBECF19CBC937445A56",
+ "29E0CAACB9BCDE4AB219A19AA77E2C9A407C98A18BD56FDF",
+ "C01326D1C26CE6592FA4E9909D93A85BE005431046661C73"
+ },
+ {
+ "139E51D5AD1EF0E1E74DD9919AE65DB6",
+ "19415EA1A2522B1B5972F5DCBEEF4E01",
+ "F0B2B2DCD9821308815ADB01F0A16B76"
+ },
+ {
+ "3124A0F9711A44FC92",
+ "3BFBAF8D7E569F06CF",
+ "D20843F00586A715DB"
+ }
+ },
+ {
+ {
+ "E376288A10BD52CB06B42B4582A425907D2DF490EC14B478507BCDE58CE95B02",
+ "FD82CFAE85B8581F1409EB62D06A98E05C401607619DE1235822E2DEB74737E1",
+ "24D9411BA4565719BE9FF1A4D91F23B3BF8980A706747077583C8EB84AF63745"
+ },
+ {
+ "FED65CDA5A5C44F619325429C78F464D271807342B10F899",
+ "E022BBFECF594E22ABC22FA25024B6FD8F61337CBD1F023D",
+ "3979354BEEB741241F0D219B5521A488F870C849275FF8B9"
+ },
+ {
+ "CE77C8D741B2B1A7E488B94EB32C96FD",
+ "D0832FF3D4B7BB73AEC7646A3686ABCF",
+ "09D8A146F559B475A6258D03BC6F8BD3"
+ },
+ {
+ "ECCD39FB9DB605BAB2",
+ "F239DEDF08B30F6EE4",
+ "2B62506A295D00687E"
+ }
+ },
+ {
+ {
+ "740A4786C73A7C6B435071A654DA8FCC75BA3299969E327A2ABC7024378CF3AA",
+ "581B63C58404AEBE49FA5FA4032918813075279E836DFE9BAEDF37D9B21ABEE1",
+ "D5FCB196868673D1FA9C8A67E6A2449354B292E1A76BA11C416A394116857B29"
+ },
+ {
+ "69AA33D68DDB6A561FB6D6218FAC0E812514782FC6059E46",
+ "45BB1795CEE5B883232EBCCB672FC9C4803C6B827825FE94",
+ "C85CC5C6CC6765EC466B8F8AC8DFC91CB916F617873AF187"
+ },
+ {
+ "590BA7DB96359F07DB2F2CE68748425C",
+ "751A8398D50B4DD24E4681B6D0E880FC",
+ "F8FD51CBD78990BD5D088ECA798DA0E6"
+ },
+ {
+ "7BB156F74A312B1A8C",
+ "57A072B4090FF9CF1B",
+ "DA47A0E70B8D24A043"
+ }
+ },
+ {
+ {
+ "0855A84EAD2176C3D2C3DE4FB868CA2C1B0DF550E187E29808C45594C070FBF4",
+ "A8420E97462B02158D2CABD1574D072F8D83123CED9BA7CEDD7C2799E168F32D",
+ "3461DEDF1B4893E182BE36017DEBC6669B15269DFA4435A31EB1A0CE6A845176"
+ },
+ {
+ "15F5DC1EE7C060FEDC9B1B43A20588E7A073A300BEFC4CAD",
+ "B5E27AC70CCA142857CB807226DC1EA9B31BE81C0FDCD3FB",
+ "29C1AA8F51A985DC7E530E6EB7AEAC246F2ED097D09851CC"
+ },
+ {
+ "25544813FC2E95AF817E0897D4E22ECD",
+ "8543EECA1724E179543979F02103C150",
+ "19603E824A47708D80E29D3A61BAE5EA"
+ },
+ {
+ "07EEB93F202A21B250",
+ "A7F91FE6CB205564F2",
+ "3BDACFAE9643C49027"
+ }
+ }
+ };
+ char testIV[][33] =
+ {
+ "0000000000000000",
+ "0102030405060708",
+ "4041424344454647",
+ "4693867334098764",
+ "6209876098547207"
+ };
+
+ for (int i = 0; i < 5; i++)
+ {
+#ifndef WITH_FIPS
+ ByteString keyData56(testKeys56[i]);
+ CPPUNIT_ASSERT(keyData56.size() == 8);
+ ByteString keyData112(testKeys112[i]);
+ CPPUNIT_ASSERT(keyData112.size() == 16);
+#endif
+ ByteString keyData168(testKeys168[i]);
+ CPPUNIT_ASSERT(keyData168.size() == 24);
+
+#ifndef WITH_FIPS
+ DESKey desKey56(56);
+ CPPUNIT_ASSERT(desKey56.setKeyBits(keyData56));
+ DESKey desKey112(112);
+ CPPUNIT_ASSERT(desKey112.setKeyBits(keyData112));
+#endif
+ DESKey desKey168(168);
+ CPPUNIT_ASSERT(desKey168.setKeyBits(keyData168));
+
+ ByteString IV(testIV[i]);
+
+ for (int j = 0; j < 4; j++)
+ {
+ ByteString plainText(testData[j]), shsmPlainText;
+ ByteString cipherText;
+ ByteString shsmCipherText, OB;
+
+#ifndef WITH_FIPS
+ // Test 56-bit key
+ cipherText = ByteString(testResult[i][j][0]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey56, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey56, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+
+ // Test 112-bit key
+ cipherText = ByteString(testResult[i][j][1]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey112, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey112, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+#endif
+
+ // Test 168-bit key
+ cipherText = ByteString(testResult[i][j][2]);
+
+ // Now, do the same thing using our DES implementation
+ shsmCipherText.wipe();
+ CPPUNIT_ASSERT(des->encryptInit(&desKey168, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->encryptUpdate(plainText, OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(des->encryptFinal(OB));
+ shsmCipherText += OB;
+
+ CPPUNIT_ASSERT(shsmCipherText == cipherText);
+
+ // Check that we can get the plain text
+ shsmPlainText.wipe();
+ CPPUNIT_ASSERT(des->decryptInit(&desKey168, SymMode::CFB, IV));
+
+ CPPUNIT_ASSERT(des->decryptUpdate(shsmCipherText, OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(des->decryptFinal(OB));
+ shsmPlainText += OB;
+
+ CPPUNIT_ASSERT(shsmPlainText == plainText);
+ }
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/DESTests.h b/SoftHSMv2/src/lib/crypto/test/DESTests.h
new file mode 100644
index 0000000..0834462
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DESTests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DESTests.h
+
+ Contains test cases to test the DES implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DESTESTS_H
+#define _SOFTHSM_V2_DESTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "SymmetricAlgorithm.h"
+
+class DESTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DESTests);
+ CPPUNIT_TEST(testBlockSize);
+ CPPUNIT_TEST(testCBC);
+ CPPUNIT_TEST(testECB);
+ CPPUNIT_TEST(testOFB);
+ CPPUNIT_TEST(testCFB);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testBlockSize();
+ void testCBC();
+ void testECB();
+ void testOFB();
+ void testCFB();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // DES instance
+ SymmetricAlgorithm* des;
+};
+
+#endif // !_SOFTHSM_V2_DESTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DHTests.cpp b/SoftHSMv2/src/lib/crypto/test/DHTests.cpp
new file mode 100644
index 0000000..354cdac
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DHTests.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHTests.cpp
+
+ Contains test cases to test the DH class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "DHTests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#include "DHParameters.h"
+#include "DHPublicKey.h"
+#include "DHPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DHTests);
+
+void DHTests::setUp()
+{
+ dh = NULL;
+
+ dh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DH);
+
+ // Check the DH object
+ CPPUNIT_ASSERT(dh != NULL);
+}
+
+void DHTests::tearDown()
+{
+ if (dh != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(dh);
+ }
+
+ fflush(stdout);
+}
+
+void DHTests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ DHParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(ap, (void*) *k));
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, p));
+
+ DHPublicKey* pub = (DHPublicKey*) kp->getPublicKey();
+ DHPrivateKey* priv = (DHPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getBitLength() == *k);
+ CPPUNIT_ASSERT(priv->getBitLength() == *k);
+
+ dh->recycleKeyPair(kp);
+
+ // Generate key-pair with a fixed private value length
+ p->setXBitLength(128);
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, p));
+
+ priv = (DHPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(priv->getX().bits() == 128);
+
+ dh->recycleParameters(p);
+ dh->recycleKeyPair(kp);
+ }
+}
+
+void DHTests::testSerialisation()
+{
+ // Generate 1024-bit parameters for testing
+ DHParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(ap, (void*) 1024));
+
+ // Set a fixed private value length
+ p->setXBitLength(128);
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dP;
+
+ CPPUNIT_ASSERT(dh->reconstructParameters(&dP, serialisedParams));
+
+ CPPUNIT_ASSERT(dP->areOfType(DHParameters::type));
+
+ DHParameters* ddP = (DHParameters*) dP;
+
+ CPPUNIT_ASSERT(p->getP() == ddP->getP());
+ CPPUNIT_ASSERT(p->getG() == ddP->getG());
+ CPPUNIT_ASSERT(p->getXBitLength() == ddP->getXBitLength());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, dP));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(dh->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ DHPrivateKey* privKey = (DHPrivateKey*) kp->getPrivateKey();
+ DHPublicKey* pubKey = (DHPublicKey*) kp->getPublicKey();
+
+ DHPrivateKey* dPrivKey = (DHPrivateKey*) dKP->getPrivateKey();
+ DHPublicKey* dPubKey = (DHPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getP() == dPrivKey->getP());
+ CPPUNIT_ASSERT(privKey->getG() == dPrivKey->getG());
+ CPPUNIT_ASSERT(privKey->getX() == dPrivKey->getX());
+
+ CPPUNIT_ASSERT(pubKey->getP() == dPubKey->getP());
+ CPPUNIT_ASSERT(pubKey->getG() == dPubKey->getG());
+ CPPUNIT_ASSERT(pubKey->getY() == dPubKey->getY());
+
+ dh->recycleParameters(p);
+ dh->recycleParameters(dP);
+ dh->recycleKeyPair(kp);
+ dh->recycleKeyPair(dKP);
+}
+
+void DHTests::testPKCS8()
+{
+ // Generate 1024-bit parameters for testing
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(&p, (void*) 1024));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ DHPrivateKey* priv = (DHPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ DHPrivateKey* dPriv = (DHPrivateKey*) dh->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getG() == dPriv->getG());
+ CPPUNIT_ASSERT(priv->getX() == dPriv->getX());
+
+ dh->recycleParameters(p);
+ dh->recycleKeyPair(kp);
+ dh->recyclePrivateKey(dPriv);
+}
+
+void DHTests::testDerivation()
+{
+ AsymmetricKeyPair* kpa;
+ AsymmetricKeyPair* kpb;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dh->generateParameters(&p, (void*) *k));
+
+ // Generate key-pairs
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kpa, p));
+ CPPUNIT_ASSERT(dh->generateKeyPair(&kpb, p));
+
+ // Derive secrets
+ SymmetricKey* sa;
+ CPPUNIT_ASSERT(dh->deriveKey(&sa, kpb->getPublicKey(), kpa->getPrivateKey()));
+ SymmetricKey* sb;
+ CPPUNIT_ASSERT(dh->deriveKey(&sb, kpa->getPublicKey(), kpb->getPrivateKey()));
+
+ // Must be the same
+ CPPUNIT_ASSERT(sa->getKeyBits() == sb->getKeyBits());
+
+ // Clean up
+ dh->recycleSymmetricKey(sa);
+ dh->recycleSymmetricKey(sb);
+ dh->recycleKeyPair(kpa);
+ dh->recycleKeyPair(kpb);
+ dh->recycleParameters(p);
+ }
+}
+
+void DHTests::testDeriveKnownVector()
+{
+ // TODO
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DHTests.h b/SoftHSMv2/src/lib/crypto/test/DHTests.h
new file mode 100644
index 0000000..e2a58ac
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DHTests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DHTests.h
+
+ Contains test cases to test the DH class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DHTESTS_H
+#define _SOFTHSM_V2_DHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class DHTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DHTests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testDerivation);
+ CPPUNIT_TEST(testDeriveKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testDerivation();
+ void testDeriveKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // DH instance
+ AsymmetricAlgorithm* dh;
+};
+
+#endif // !_SOFTHSM_V2_DHTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/DSATests.cpp b/SoftHSMv2/src/lib/crypto/test/DSATests.cpp
new file mode 100644
index 0000000..80f2514
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DSATests.cpp
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSATests.cpp
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "DSATests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#include "DSAParameters.h"
+#include "DSAPublicKey.h"
+#include "DSAPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DSATests);
+
+void DSATests::setUp()
+{
+ dsa = NULL;
+
+ dsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::DSA);
+
+ // Check the DSA object
+ CPPUNIT_ASSERT(dsa != NULL);
+}
+
+void DSATests::tearDown()
+{
+ if (dsa != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(dsa);
+ }
+
+ fflush(stdout);
+}
+
+void DSATests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+#ifndef WITH_FIPS
+ keySizes.push_back(1024);
+ keySizes.push_back(1536);
+#else
+ keySizes.push_back(1024);
+#endif
+#ifndef WITH_BOTAN
+ keySizes.push_back(2048);
+#endif
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ DSAParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(ap, (void*) *k));
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, p));
+
+ DSAPublicKey* pub = (DSAPublicKey*) kp->getPublicKey();
+ DSAPrivateKey* priv = (DSAPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getBitLength() == *k);
+ CPPUNIT_ASSERT(priv->getBitLength() == *k);
+
+ dsa->recycleParameters(p);
+ dsa->recycleKeyPair(kp);
+ }
+}
+
+void DSATests::testSerialisation()
+{
+ // Generate 1024-bit parameters for testing
+ DSAParameters* p;
+ AsymmetricParameters** ap = (AsymmetricParameters**) &p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(ap, (void*) 1024));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dP;
+
+ CPPUNIT_ASSERT(dsa->reconstructParameters(&dP, serialisedParams));
+
+ CPPUNIT_ASSERT(dP->areOfType(DSAParameters::type));
+
+ DSAParameters* ddP = (DSAParameters*) dP;
+
+ CPPUNIT_ASSERT(p->getP() == ddP->getP());
+ CPPUNIT_ASSERT(p->getQ() == ddP->getQ());
+ CPPUNIT_ASSERT(p->getG() == ddP->getG());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, dP));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(dsa->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ DSAPrivateKey* privKey = (DSAPrivateKey*) kp->getPrivateKey();
+ DSAPublicKey* pubKey = (DSAPublicKey*) kp->getPublicKey();
+
+ DSAPrivateKey* dPrivKey = (DSAPrivateKey*) dKP->getPrivateKey();
+ DSAPublicKey* dPubKey = (DSAPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getP() == dPrivKey->getP());
+ CPPUNIT_ASSERT(privKey->getQ() == dPrivKey->getQ());
+ CPPUNIT_ASSERT(privKey->getG() == dPrivKey->getG());
+ CPPUNIT_ASSERT(privKey->getX() == dPrivKey->getX());
+
+ CPPUNIT_ASSERT(pubKey->getP() == dPubKey->getP());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+ CPPUNIT_ASSERT(pubKey->getG() == dPubKey->getG());
+ CPPUNIT_ASSERT(pubKey->getY() == dPubKey->getY());
+
+ dsa->recycleParameters(p);
+ dsa->recycleParameters(dP);
+ dsa->recycleKeyPair(kp);
+ dsa->recycleKeyPair(dKP);
+}
+
+void DSATests::testPKCS8()
+{
+ // Generate 1024-bit parameters for testing
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(&p, (void*) 1024));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ DSAPrivateKey* priv = (DSAPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ DSAPrivateKey* dPriv = (DSAPrivateKey*) dsa->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
+ CPPUNIT_ASSERT(priv->getG() == dPriv->getG());
+ CPPUNIT_ASSERT(priv->getX() == dPriv->getX());
+
+ dsa->recycleParameters(p);
+ dsa->recycleKeyPair(kp);
+ dsa->recyclePrivateKey(dPriv);
+}
+
+void DSATests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+#ifndef WITH_FIPS
+ keySizes.push_back(1024);
+ keySizes.push_back(1536);
+#else
+ keySizes.push_back(1024);
+#endif
+#ifndef WITH_BOTAN
+ keySizes.push_back(2048);
+#endif
+
+ // Mechanisms to test
+ std::vector<AsymMech::Type> mechanisms;
+ mechanisms.push_back(AsymMech::DSA_SHA1);
+ mechanisms.push_back(AsymMech::DSA_SHA224);
+ mechanisms.push_back(AsymMech::DSA_SHA256);
+
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ // Generate parameters
+ AsymmetricParameters* p;
+
+ CPPUNIT_ASSERT(dsa->generateParameters(&p, (void*) *k));
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(dsa->generateKeyPair(&kp, p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Test mechanisms that perform internal hashing
+ for (std::vector<AsymMech::Type>::iterator m = mechanisms.begin(); m != mechanisms.end(); m++)
+ {
+ ByteString blockSignature, singlePartSignature;
+
+ // Sign the data in blocks
+ CPPUNIT_ASSERT(dsa->signInit(kp->getPrivateKey(), *m));
+ CPPUNIT_ASSERT(dsa->signUpdate(dataToSign.substr(0, 134)));
+ CPPUNIT_ASSERT(dsa->signUpdate(dataToSign.substr(134, 289)));
+ CPPUNIT_ASSERT(dsa->signUpdate(dataToSign.substr(134 + 289)));
+ CPPUNIT_ASSERT(dsa->signFinal(blockSignature));
+
+ // Sign the data in one pass
+ CPPUNIT_ASSERT(dsa->sign(kp->getPrivateKey(), dataToSign, singlePartSignature, *m));
+
+ // Now perform multi-pass verification
+ CPPUNIT_ASSERT(dsa->verifyInit(kp->getPublicKey(), *m));
+ CPPUNIT_ASSERT(dsa->verifyUpdate(dataToSign.substr(0, 125)));
+ CPPUNIT_ASSERT(dsa->verifyUpdate(dataToSign.substr(125, 247)));
+ CPPUNIT_ASSERT(dsa->verifyUpdate(dataToSign.substr(125 + 247)));
+ CPPUNIT_ASSERT(dsa->verifyFinal(blockSignature));
+
+ // And single-pass verification
+ CPPUNIT_ASSERT(dsa->verify(kp->getPublicKey(), dataToSign, singlePartSignature, *m));
+ }
+
+ // Test mechanisms that do not perform internal hashing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, *k >= 2048 ? 32 : 20));
+
+ // Sign the data
+ ByteString signature;
+ CPPUNIT_ASSERT(dsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::DSA));
+
+ // Verify the signature
+ CPPUNIT_ASSERT(dsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::DSA));
+
+ dsa->recycleKeyPair(kp);
+ dsa->recycleParameters(p);
+ }
+}
+
+void DSATests::testSignVerifyKnownVector()
+{
+ DSAPublicKey* pubKey1 = (DSAPublicKey*) dsa->newPublicKey();
+ DSAPublicKey* pubKey2 = (DSAPublicKey*) dsa->newPublicKey();
+ DSAPrivateKey* privKey1 = (DSAPrivateKey*) dsa->newPrivateKey();
+ DSAPrivateKey* privKey2 = (DSAPrivateKey*) dsa->newPrivateKey();
+
+ // Reconstruct public and private key #1
+ ByteString p1 = "e0a67598cd1b763bc98c8abb333e5dda0cd3aa0e5e1fb5ba8a7b4eabc10ba338fae06dd4b90fda70d7cf0cb0c638be3341bec0af8a7330a3307ded2299a0ee606df035177a239c34a912c202aa5f83b9c4a7cf0235b5316bfc6efb9a248411258b30b839af172440f32563056cb67a861158ddd90e6a894c72a5bbef9e286c6b";
+ ByteString q1 = "e950511eab424b9a19a2aeb4e159b7844c589c4f";
+ ByteString g1 = "d29d5121b0423c2769ab21843e5a3240ff19cacc792264e3bb6be4f78edd1b15c4dff7f1d905431f0ab16790e1f773b5ce01c804e509066a9919f5195f4abc58189fd9ff987389cb5bedf21b4dab4f8b76a055ffe2770988fe2ec2de11ad92219f0b351869ac24da3d7ba87011a701ce8ee7bfe49486ed4527b7186ca4610a75";
+ ByteString x1 = "d0ec4e50bb290a42e9e355c73d8809345de2e139";
+ ByteString y1 = "25282217f5730501dd8dba3edfcf349aaffec20921128d70fac44110332201bba3f10986140cbb97c726938060473c8ec97b4731db004293b5e730363609df9780f8d883d8c4d41ded6a2f1e1bbbdc979e1b9d6d3c940301f4e978d65b19041fcf1e8b518f5c0576c770fe5a7a485d8329ee2914a2de1b5da4a6128ceab70f79";
+
+ pubKey1->setP(p1);
+ pubKey1->setQ(q1);
+ pubKey1->setG(g1);
+ pubKey1->setY(y1);
+ privKey1->setP(p1);
+ privKey1->setQ(q1);
+ privKey1->setG(g1);
+ privKey1->setX(x1);
+
+ // Test with key #1
+ ByteString data1 = "616263"; // "abc"
+ ByteString goodSignature1 = "636155ac9a4633b4665d179f9e4117df68601f346c540b02d9d4852f89df8cfc99963204f4347704";
+ ByteString badSignature1 = "636155ac9a4633b4665d179f9e4117df68601f346c540b02d9d4852f89df8cfc99963204f4347705";
+
+ // Reconstruct public and private key #2
+ ByteString p2 = "f56c2a7d366e3ebdeaa1891fd2a0d099436438a673fed4d75f594959cffebca7be0fc72e4fe67d91d801cba0693ac4ed9e411b41d19e2fd1699c4390ad27d94c69c0b143f1dc88932cfe2310c886412047bd9b1c7a67f8a25909132627f51a0c866877e672e555342bdf9355347dbd43b47156b2c20bad9d2b071bc2fdcf9757f75c168c5d9fc43131be162a0756d1bdec2ca0eb0e3b018a8b38d3ef2487782aeb9fbf99d8b30499c55e4f61e5c7dcee2a2bb55bd7f75fcdf00e48f2e8356bdb59d86114028f67b8e07b127744778aff1cf1399a4d679d92fde7d941c5c85c5d7bff91ba69f9489d531d1ebfa727cfda651390f8021719fa9f7216ceb177bd75";
+ ByteString q2 = "c24ed361870b61e0d367f008f99f8a1f75525889c89db1b673c45af5867cb467";
+ ByteString g2 = "8dc6cc814cae4a1c05a3e186a6fe27eaba8cdb133fdce14a963a92e809790cba096eaa26140550c129fa2b98c16e84236aa33bf919cd6f587e048c52666576db6e925c6cbe9b9ec5c16020f9a44c9f1c8f7a8e611c1f6ec2513ea6aa0b8d0f72fed73ca37df240db57bbb27431d618697b9e771b0b301d5df05955425061a30dc6d33bb6d2a32bd0a75a0a71d2184f506372abf84a56aeeea8eb693bf29a640345fa1298a16e85421b2208d00068a5a42915f82cf0b858c8fa39d43d704b6927e0b2f916304e86fb6a1b487f07d8139e428bb096c6d67a76ec0b8d4ef274b8a2cf556d279ad267ccef5af477afed029f485b5597739f5d0240f67c2d948a6279";
+ ByteString x2 = "0caf2ef547ec49c4f3a6fe6df4223a174d01f2c115d49a6f73437c29a2a8458c";
+ ByteString y2 = "2828003d7c747199143c370fdd07a2861524514acc57f63f80c38c2087c6b795b62de1c224bf8d1d1424e60ce3f5ae3f76c754a2464af292286d873a7a30b7eacbbc75aafde7191d9157598cdb0b60e0c5aa3f6ebe425500c611957dbf5ed35490714a42811fdcdeb19af2ab30beadff2907931cee7f3b55532cffaeb371f84f01347630eb227a419b1f3f558bc8a509d64a765d8987d493b007c4412c297caf41566e26faee475137ec781a0dc088a26c8804a98c23140e7c936281864b99571ee95c416aa38ceebb41fdbff1eb1d1dc97b63ce1355257627c8b0fd840ddb20ed35be92f08c49aea5613957d7e5c7a6d5a5834b4cb069e0831753ecf65ba02b";
+
+ pubKey2->setP(p2);
+ pubKey2->setQ(q2);
+ pubKey2->setG(g2);
+ pubKey2->setY(y2);
+ privKey2->setP(p2);
+ privKey2->setQ(q2);
+ privKey2->setG(g2);
+ privKey2->setX(x2);
+
+ // Test with key #2
+ ByteString data2 = "616263"; // "abc"
+ ByteString goodSignature2 = "315c875dcd4850e948b8ac42824e9483a32d5ba5abe0681b9b9448d444f2be3c89718d12e54a8d9ed066e4a55f7ed5a2229cd23b9a3cee78f83ed6aa61f6bcb9";
+ ByteString badSignature2 = "315c875dcd4850e948b8ac42824e9483a32d5ba5abe0681b9b9448d444f2be3c89718d12e54a8d9ed066e4a55f7ed5a2229cd23b9a3cee78f83ed6aa61f6bcb8";
+
+ CPPUNIT_ASSERT(dsa->verify(pubKey1, data1, goodSignature1, AsymMech::DSA_SHA1));
+ CPPUNIT_ASSERT(!dsa->verify(pubKey1, data1, badSignature1, AsymMech::DSA_SHA1));
+ CPPUNIT_ASSERT(dsa->verify(pubKey2, data2, goodSignature2, AsymMech::DSA_SHA256));
+ CPPUNIT_ASSERT(!dsa->verify(pubKey2, data2, badSignature2, AsymMech::DSA_SHA256));
+
+ dsa->recyclePublicKey(pubKey1);
+ dsa->recyclePublicKey(pubKey2);
+ dsa->recyclePrivateKey(privKey1);
+ dsa->recyclePrivateKey(privKey2);
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/DSATests.h b/SoftHSMv2/src/lib/crypto/test/DSATests.h
new file mode 100644
index 0000000..446733a
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/DSATests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ DSATests.h
+
+ Contains test cases to test the DSA class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_DSATESTS_H
+#define _SOFTHSM_V2_DSATESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class DSATests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(DSATests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // DSA instance
+ AsymmetricAlgorithm* dsa;
+};
+
+#endif // !_SOFTHSM_V2_DSATESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp b/SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp
new file mode 100644
index 0000000..1646fd8
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDHTests.cpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDHTests.cpp
+
+ Contains test cases to test the ECDH class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "ECDHTests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#ifdef WITH_ECC
+#include "ECParameters.h"
+#include "ECPublicKey.h"
+#include "ECPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ECDHTests);
+
+void ECDHTests::setUp()
+{
+ ecdh = NULL;
+
+ ecdh = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDH);
+
+ // Check the ECDH object
+ CPPUNIT_ASSERT(ecdh != NULL);
+}
+
+void ECDHTests::tearDown()
+{
+ if (ecdh != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdh);
+ }
+
+ fflush(stdout);
+}
+
+void ECDHTests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Curves to test
+ std::vector<ByteString> curves;
+ // Add X9.62 prime256v1
+ curves.push_back(ByteString("06082a8648ce3d030107"));
+ // Add secp384r1
+ curves.push_back(ByteString("06052b81040022"));
+
+ for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++)
+ {
+ // Set domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(*c);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kp, p));
+
+ ECPublicKey* pub = (ECPublicKey*) kp->getPublicKey();
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getEC() == *c);
+ CPPUNIT_ASSERT(priv->getEC() == *c);
+
+ ecdh->recycleParameters(p);
+ ecdh->recycleKeyPair(kp);
+ }
+}
+
+void ECDHTests::testSerialisation()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dEC;
+
+ CPPUNIT_ASSERT(ecdh->reconstructParameters(&dEC, serialisedParams));
+
+ CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type));
+
+ ECParameters* ddEC = (ECParameters*) dEC;
+
+ CPPUNIT_ASSERT(p->getEC() == ddEC->getEC());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kp, dEC));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(ecdh->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ ECPrivateKey* privKey = (ECPrivateKey*) kp->getPrivateKey();
+ ECPublicKey* pubKey = (ECPublicKey*) kp->getPublicKey();
+
+ ECPrivateKey* dPrivKey = (ECPrivateKey*) dKP->getPrivateKey();
+ ECPublicKey* dPubKey = (ECPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getEC() == dPrivKey->getEC());
+ CPPUNIT_ASSERT(privKey->getD() == dPrivKey->getD());
+
+ CPPUNIT_ASSERT(pubKey->getEC() == dPubKey->getEC());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+
+ ecdh->recycleParameters(p);
+ ecdh->recycleParameters(dEC);
+ ecdh->recycleKeyPair(kp);
+ ecdh->recycleKeyPair(dKP);
+}
+
+void ECDHTests::testPKCS8()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ ECPrivateKey* dPriv = (ECPrivateKey*) ecdh->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getEC() == dPriv->getEC());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+
+ ecdh->recycleParameters(p);
+ ecdh->recycleKeyPair(kp);
+ ecdh->recyclePrivateKey(dPriv);
+}
+
+void ECDHTests::testDerivation()
+{
+ AsymmetricKeyPair* kpa;
+ AsymmetricKeyPair* kpb;
+ ECParameters* p;
+
+ // Curves to test
+ std::vector<ByteString> curves;
+ // Add X9.62 prime256v1
+ curves.push_back(ByteString("06082a8648ce3d030107"));
+ // Add secp384r1
+ curves.push_back(ByteString("06052b81040022"));
+
+ for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++)
+ {
+ // Get parameters
+ p = new ECParameters;
+ CPPUNIT_ASSERT(p != NULL);
+ p->setEC(*c);
+
+ // Generate key-pairs
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kpa, p));
+ CPPUNIT_ASSERT(ecdh->generateKeyPair(&kpb, p));
+
+ // Derive secrets
+ SymmetricKey* sa;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sa, kpb->getPublicKey(), kpa->getPrivateKey()));
+ SymmetricKey* sb;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sb, kpa->getPublicKey(), kpb->getPrivateKey()));
+
+ // Must be the same
+ CPPUNIT_ASSERT(sa->getKeyBits() == sb->getKeyBits());
+
+ // Clean up
+ ecdh->recycleSymmetricKey(sa);
+ ecdh->recycleSymmetricKey(sb);
+ ecdh->recycleKeyPair(kpa);
+ ecdh->recycleKeyPair(kpb);
+ ecdh->recycleParameters(p);
+ }
+}
+
+void ECDHTests::testDeriveKnownVector()
+{
+ ECPublicKey* pubKeya = (ECPublicKey*) ecdh->newPublicKey();
+ ECPublicKey* pubKeyb = (ECPublicKey*) ecdh->newPublicKey();
+ ECPrivateKey* privKeya = (ECPrivateKey*) ecdh->newPrivateKey();
+ ECPrivateKey* privKeyb = (ECPrivateKey*) ecdh->newPrivateKey();
+
+ // Reconstruct public and private key for Alice
+ ByteString ec = "06082a8648ce3d030107"; // X9.62 prime256v1
+ ByteString da = "c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433";
+ // add 04 (ASN_String) <len+1> 04 (UNCOMPRESSED) in front!
+ ByteString qa = "044104dad0b65394221cf9b051e1feca5787d098dfe637fc90b9ef945d0c37725811805271a0461cdb8252d61f1c456fa3e59ab1f45b33accf5f58389e0577b8990bb3";
+
+ pubKeya->setEC(ec);
+ pubKeya->setQ(qa);
+ privKeya->setEC(ec);
+ privKeya->setD(da);
+
+ // Reconstruct public and private key for Bob
+ ByteString db = "c6ef9c5d78ae012a011164acb397ce2088685d8f06bf9be0b283ab46476bee53";
+ ByteString qb = "044104d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab";
+
+ pubKeyb->setEC(ec);
+ pubKeyb->setQ(qb);
+ privKeyb->setEC(ec);
+ privKeyb->setD(db);
+
+ // Test
+ ByteString expected = "d6840f6b42f6edafd13116e0e12565202fef8e9ece7dce03812464d04b9442de";
+ SymmetricKey* sa;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sa, pubKeya, privKeyb));
+ CPPUNIT_ASSERT(sa->getKeyBits() == expected);
+ SymmetricKey* sb;
+ CPPUNIT_ASSERT(ecdh->deriveKey(&sb, pubKeyb, privKeya));
+ CPPUNIT_ASSERT(sb->getKeyBits() == expected);
+
+ ecdh->recyclePublicKey(pubKeya);
+ ecdh->recyclePublicKey(pubKeyb);
+ ecdh->recyclePrivateKey(privKeya);
+ ecdh->recyclePrivateKey(privKeyb);
+ ecdh->recycleSymmetricKey(sa);
+ ecdh->recycleSymmetricKey(sb);
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDHTests.h b/SoftHSMv2/src/lib/crypto/test/ECDHTests.h
new file mode 100644
index 0000000..81cf6d5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDHTests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDHTests.h
+
+ Contains test cases to test the ECDH class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECDHTESTS_H
+#define _SOFTHSM_V2_ECDHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class ECDHTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ECDHTests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testDerivation);
+ CPPUNIT_TEST(testDeriveKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testDerivation();
+ void testDeriveKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // ECDH instance
+ AsymmetricAlgorithm* ecdh;
+};
+
+#endif // !_SOFTHSM_V2_ECDHTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp b/SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp
new file mode 100644
index 0000000..3c29d06
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDSATests.cpp
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDSATests.cpp
+
+ Contains test cases to test the ECDSA class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <utility>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "ECDSATests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#ifdef WITH_ECC
+#include "ECParameters.h"
+#include "ECPublicKey.h"
+#include "ECPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ECDSATests);
+
+void ECDSATests::setUp()
+{
+ ecdsa = NULL;
+
+ ecdsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::ECDSA);
+
+ // Check the ECDSA object
+ CPPUNIT_ASSERT(ecdsa != NULL);
+}
+
+void ECDSATests::tearDown()
+{
+ if (ecdsa != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(ecdsa);
+ }
+
+ fflush(stdout);
+}
+
+void ECDSATests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Curves to test
+ std::vector<ByteString> curves;
+ // Add X9.62 prime256v1
+ curves.push_back(ByteString("06082a8648ce3d030107"));
+ // Add secp384r1
+ curves.push_back(ByteString("06052b81040022"));
+ // Add secp521r1
+ curves.push_back(ByteString("06052b81040023"));
+
+ for (std::vector<ByteString>::iterator c = curves.begin(); c != curves.end(); c++)
+ {
+ // Set domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(*c);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, p));
+
+ ECPublicKey* pub = (ECPublicKey*) kp->getPublicKey();
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getEC() == *c);
+ CPPUNIT_ASSERT(priv->getEC() == *c);
+
+ ecdsa->recycleParameters(p);
+ ecdsa->recycleKeyPair(kp);
+ }
+}
+
+void ECDSATests::testSerialisation()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dEC;
+
+ CPPUNIT_ASSERT(ecdsa->reconstructParameters(&dEC, serialisedParams));
+
+ CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type));
+
+ ECParameters* ddEC = (ECParameters*) dEC;
+
+ CPPUNIT_ASSERT(p->getEC() == ddEC->getEC());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, dEC));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(ecdsa->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ ECPrivateKey* privKey = (ECPrivateKey*) kp->getPrivateKey();
+ ECPublicKey* pubKey = (ECPublicKey*) kp->getPublicKey();
+
+ ECPrivateKey* dPrivKey = (ECPrivateKey*) dKP->getPrivateKey();
+ ECPublicKey* dPubKey = (ECPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getEC() == dPrivKey->getEC());
+ CPPUNIT_ASSERT(privKey->getD() == dPrivKey->getD());
+
+ CPPUNIT_ASSERT(pubKey->getEC() == dPubKey->getEC());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+
+ ecdsa->recycleParameters(p);
+ ecdsa->recycleParameters(dEC);
+ ecdsa->recycleKeyPair(kp);
+ ecdsa->recycleKeyPair(dKP);
+}
+
+void ECDSATests::testPKCS8()
+{
+ // Get prime256v1 domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06082a8648ce3d030107"));
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ ECPrivateKey* priv = (ECPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ ECPrivateKey* dPriv = (ECPrivateKey*) ecdsa->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getEC() == dPriv->getEC());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+
+ ecdsa->recycleParameters(p);
+ ecdsa->recycleKeyPair(kp);
+ ecdsa->recyclePrivateKey(dPriv);
+}
+
+void ECDSATests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+ ECParameters *p;
+
+ // Curves/Hashes to test
+ std::vector<std::pair<ByteString, HashAlgo::Type> > totest;
+ // Add X9.62 prime256v1
+ totest.push_back(std::make_pair(ByteString("06082a8648ce3d030107"), HashAlgo::SHA256));
+ // Add secp384r1
+ totest.push_back(std::make_pair(ByteString("06052b81040022"), HashAlgo::SHA384));
+ // Add secp521r1
+ totest.push_back(std::make_pair(ByteString("06052b81040023"), HashAlgo::SHA384));
+
+ for (std::vector<std::pair<ByteString, HashAlgo::Type> >::iterator k = totest.begin(); k != totest.end(); k++)
+ {
+ // Get parameters
+ p = new ECParameters;
+ CPPUNIT_ASSERT(p != NULL);
+ p->setEC(k->first);
+ HashAlgorithm *hash;
+ hash = CryptoFactory::i()->getHashAlgorithm(k->second);
+ CPPUNIT_ASSERT(hash != NULL);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(ecdsa->generateKeyPair(&kp, p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+ CPPUNIT_ASSERT(rng != NULL);
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Sign the data
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(dataToSign));
+ ByteString hResult;
+ CPPUNIT_ASSERT(hash->hashFinal(hResult));
+ ByteString sig;
+ CPPUNIT_ASSERT(ecdsa->sign(kp->getPrivateKey(), hResult, sig, AsymMech::ECDSA));
+
+ // And verify it
+ CPPUNIT_ASSERT(ecdsa->verify(kp->getPublicKey(), hResult, sig, AsymMech::ECDSA));
+
+ ecdsa->recycleKeyPair(kp);
+ ecdsa->recycleParameters(p);
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ }
+}
+
+void ECDSATests::testSignVerifyKnownVector()
+{
+ ECPublicKey* pubKey1 = (ECPublicKey*) ecdsa->newPublicKey();
+ ECPublicKey* pubKey2 = (ECPublicKey*) ecdsa->newPublicKey();
+ ECPrivateKey* privKey1 = (ECPrivateKey*) ecdsa->newPrivateKey();
+ ECPrivateKey* privKey2 = (ECPrivateKey*) ecdsa->newPrivateKey();
+ HashAlgorithm* hash1 = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA256);
+ HashAlgorithm* hash2 = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA384);
+
+ // Reconstruct public and private key #1
+ ByteString ec1 = "06082a8648ce3d030107"; // X9.62 prime256v1
+ ByteString d1 = "dc51d3866a15bacde33d96f992fca99da7e6ef0934e7097559c27f1614c88a7f";
+ // add 04 (ASN_String) <len+1> 04 (UNCOMPRESSED) in front!
+ ByteString q1 = "0441042442a5cc0ecd015fa3ca31dc8e2bbc70bf42d60cbca20085e0822cb04235e9706fc98bd7e50211a4a27102fa3549df79ebcb4bf246b80945cddfe7d509bbfd7d";
+
+ pubKey1->setEC(ec1);
+ pubKey1->setQ(q1);
+ privKey1->setEC(ec1);
+ privKey1->setD(d1);
+ CPPUNIT_ASSERT(hash1 != NULL);
+
+ // Test with key #1
+ ByteString data1 = "616263"; // "abc"
+ ByteString goodSignature1 = "cb28e0999b9c7715fd0a80d8e47a77079716cbbf917dd72e97566ea1c066957c86fa3bb4e26cad5bf90b7f81899256ce7594bb1ea0c89212748bff3b3d5b0315";
+ ByteString badSignature1 = "cb28e0999b9c7715fd0a80d8e47a77079716cbbf917dd72e97566ea1c066957c86fa3bb4e26cad5bf90b7f81899256ce7594bb1ea0c89212748bff3b3d5b0316";
+
+ // Reconstruct public and private key #2
+ ByteString ec2 = "06052b81040022"; // secp384r1
+ ByteString d2 = "0beb646634ba87735d77ae4809a0ebea865535de4c1e1dcb692e84708e81a5af62e528c38b2a81b35309668d73524d9f";
+ // add 04 (ASN_String) <len+1> 04 (UNCOMPRESSED) in front!
+ ByteString q2 = "04610496281bf8dd5e0525ca049c048d345d3082968d10fedf5c5aca0c64e6465a97ea5ce10c9dfec21797415710721f437922447688ba94708eb6e2e4d59f6ab6d7edff9301d249fe49c33096655f5d502fad3d383b91c5e7edaa2b714cc99d5743ca";
+
+ pubKey2->setEC(ec2);
+ pubKey2->setQ(q2);
+ privKey2->setEC(ec2);
+ privKey2->setD(d2);
+ CPPUNIT_ASSERT(hash2 != NULL);
+
+ // Test with key #2
+ ByteString data2 = "616263"; // "abc"
+ ByteString goodSignature2 = "fb017b914e29149432d8bac29a514640b46f53ddab2c69948084e2930f1c8f7e08e07c9c63f2d21a07dcb56a6af56eb3b263a1305e057f984d38726a1b46874109f417bca112674c528262a40a629af1cbb9f516ce0fa7d2ff630863a00e8b9f";
+ ByteString badSignature2 = "fb017b914e29149432d8bac29a514640b46f53ddab2c69948084e2930f1c8f7e08e07c9c63f2d21a07dcb56a6af56eb3b263a1305e057f984d38726a1b46874109f417bca112674c528262a40a629af1cbb9f516ce0fa7d2ff630863a00e8b9e";
+
+ CPPUNIT_ASSERT(hash1->hashInit());
+ CPPUNIT_ASSERT(hash1->hashUpdate(data1));
+ ByteString hResult1;
+ CPPUNIT_ASSERT(hash1->hashFinal(hResult1));
+ CPPUNIT_ASSERT(ecdsa->verify(pubKey1, hResult1, goodSignature1, AsymMech::ECDSA));
+ CPPUNIT_ASSERT(!ecdsa->verify(pubKey1, hResult1, badSignature1, AsymMech::ECDSA));
+ CPPUNIT_ASSERT(hash2->hashInit());
+ CPPUNIT_ASSERT(hash2->hashUpdate(data2));
+ ByteString hResult2;
+ CPPUNIT_ASSERT(hash2->hashFinal(hResult2));
+ CPPUNIT_ASSERT(ecdsa->verify(pubKey2, hResult2, goodSignature2, AsymMech::ECDSA));
+ CPPUNIT_ASSERT(!ecdsa->verify(pubKey2, hResult2, badSignature2, AsymMech::ECDSA));
+
+ ecdsa->recyclePublicKey(pubKey1);
+ ecdsa->recyclePublicKey(pubKey2);
+ ecdsa->recyclePrivateKey(privKey1);
+ ecdsa->recyclePrivateKey(privKey2);
+ CryptoFactory::i()->recycleHashAlgorithm(hash1);
+ CryptoFactory::i()->recycleHashAlgorithm(hash2);
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/test/ECDSATests.h b/SoftHSMv2/src/lib/crypto/test/ECDSATests.h
new file mode 100644
index 0000000..70b3345
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ECDSATests.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ECDSATests.h
+
+ Contains test cases to test the ECDSA class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ECDSATESTS_H
+#define _SOFTHSM_V2_ECDSATESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class ECDSATests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(ECDSATests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // ECDSA instance
+ AsymmetricAlgorithm* ecdsa;
+};
+
+#endif // !_SOFTHSM_V2_ECDSATESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp b/SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp
new file mode 100644
index 0000000..91f6876
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/GOSTTests.cpp
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTTests.cpp
+
+ Contains test cases to test the GOST implementations
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "GOSTTests.h"
+#include "CryptoFactory.h"
+#include <stdio.h>
+#include "AsymmetricAlgorithm.h"
+#include "AsymmetricKeyPair.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+#ifdef WITH_GOST
+#include "ECParameters.h"
+#include "GOSTPublicKey.h"
+#include "GOSTPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(GOSTTests);
+
+void GOSTTests::setUp()
+{
+ hash = NULL;
+ mac = NULL;
+ gost = NULL;
+ rng = NULL;
+
+ gost = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::GOST);
+
+ // Check the GOST object
+ CPPUNIT_ASSERT(gost != NULL);
+}
+
+void GOSTTests::tearDown()
+{
+ if (hash != NULL)
+ {
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ }
+
+ if (mac != NULL)
+ {
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+ }
+
+ if (gost != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(gost);
+ }
+
+ fflush(stdout);
+}
+
+void GOSTTests::testHash()
+{
+ char testData[4096] = "FE5A773751EAB2F18921C04806D6907444557B4469CDA7C822288E5065DA58F448A27FA0B4C8786853F246B093E3DBFDC332759D7764B6D057895184D9B82E626DF70AEB99B969EA35E5BE4D50C7406EA4A7450AC063933F96F77960EE711A445593119CF69061702CB4797F214FA440C94127E3DCD92F2C71B39D354C6F4284E030DCBFCB91EA5E543E0E3560ECD355091850BA080287BD87B74BB84A8892E0F2172F136D187305179F23EB8296BF1798405BAB52E201F22BCA5B793C5BA6F2CA15F154598EEC73E7E61B405262F6FE5FDC0F9AE0528801C3F965956C79A6C6805EDD0C6515AEA27D1DB9D70A56B0F13A544429C448FB6DB390C0E367EDF997E0B681ADE3846D77D1898F06FB60CB2384015F3749BD1E8163E532529E4D3BB8B200BBE79DA76D4865621FF2E583A1A1F8EBFB7A51B65DC9152B173A7DF91C6943F2FE497CDBC306827146199ADA925DD42B8A48429F5B6E3670AA85A44BDFAB3D273EA6711B996B5C27E04949BE61ED9ECB932F429ADCF31A2E0E9F83FCB1CE6BC0EE81627D1F9D08ECD599F16A1D68B256B002E90A8B4E5830A049ECE9ADF1D50C027EC537DD5412AA1509E91CEF358B2D495D3B37651987F51D9643A5AF2E0EF3D8C02E6023BB76FF8F1EB5CD018FA32BD7886A1A46A7D5CA15E4E0CDB793F0C1986EF4480305801A518B1D4596AAA741C093FC7AD075B637B1B2CC4DA33B6EB6D549001B33E1753C9C4358FB541FDE6541238BD011CD8ACAFB4CFF15B289872956DFBCC732593E838B6300E48ED3455CD101920114640A5B7C1250E419B7D771EC65934F53176BBD7A61A36D6D3D64A1F29C3D41745993636F812930E2936E9ED34E92A3C31239176ED3F78461EE80C54D92CBD9EF9F5746F8069809A38549FC7A8FD99FB350C27230966D6001D3136114A7BDCDEE495B72E4A633845BC88400DEDADC2FA2CD8640049CDB4F8F695C45EACF24FD573E1FB1670F688C9D7706A9AE9EB30E0DFDD54C7F3F3EE6F9BBFBBED6DB6E7C7B979E677DCD8457949DC271BD6ACB445B16247D8DAC1B59D45B8FFBBFDAEA20A5C450E0F93B399AE69887E1C721B0EF86C8CD37FC7514C4F2B70AA1E757DE95DCC3B74C6E18E51D272D433330826435B7CBA6C099558B51E408B1BFE60E876141A74195A00BF914F2536D92170FB43E078D98F784E6F150ED2B16DB5B629EBABF16444639C87A544050E03FB7CCD538DA29C45CE764F68682B48BF8AE5ED43064E833338A88605B1743FEB025D5F5607BB13A2078A99924A2D4818CD582ACDC1556FAEBA70959DE8498F3FCBF85BD269A7DF23A3AD5704908978031667C7BF4A85D1EF42F3ED144670E6EEB5D8213DB43B0B7B43767FD4277EF0EC52B5718A7D187A003DE8E5DFF9C3A3CD520615FB9B52281506E5BB033818E0912980A8BCAA54E21C5630B9E863C83";
+ char testResult[512] = "3EC65819A084AD30712C4B3EB69CE130A8C7221EA3D8A9996D4BA6F298BC39F9";
+
+ // Get a GOST R 34.11-94 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::GOST)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), gostHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(gostHash));
+
+ CPPUNIT_ASSERT(osslHash == gostHash);
+
+ // Now recreate the hash in a single part operation
+ gostHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(gostHash));
+
+ CPPUNIT_ASSERT(osslHash == gostHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void GOSTTests::testHmac()
+{
+ char testData[4096] = "1450414E94B2CEA9E202B8ACC9C358EBA5334C20CF1B7D13E8B79BE63A0A938A340CF710D539262F406787AF7188990C7D75780C265E37750510FA6AAA742D01C753548219C20B1283CCA9D30AA5A8650D0C5EE63FE10268F9CD5996F8DB0158C6FAD147AE41C0E565F6FBC85115E17BB0B448208075D1CF79CF70574098E7116A5C5EFFDB05DCD83E71DB4860B3AEC2612FB9DE1B010229A413055724AB07F4131B04800286D3C4895A158E7B1301F8010E718C76CC69B34C643D2B1EACC00F9CD0DEBC83425256B2524B34D61EBA32FE5F79FE0A1F9360E3CFB4C88CE7CC3C36E969A37827AD5FD79BFAC08CCA1786F30F34ADC605545F04BA96CA4A4E3DF7FEC36E43406E9CD68D708CBAC4C54B2E18E38535BD1A8029FD7393B5462AB688F8146445295E5473B15B26EC129A24C78B7198D558209E827C38426D747FB0D2B04F1EE7B142B7B736EFF4B819B5420F4642E77181617BEC8074109B463F4C53A6F3507A0B4419B2D7CC0B6CF89FAA2CAEAC17BF19E6A94E0BF346D0F77C47EDB29CBD204483E53853401779AEA0998B993E39EA4C5003326C017A5A3BD0C5591D4F822641FAE9DBDF78B15DC5BA326150F89C864774A8DBF6464B259A29C00D9BCC63F61B3B45FF19E6FD0CDA2BE17608488B0E5C6CC5C596F035C8E580C30FC7C6FE2428F3509511B9D7FE77CF53C5B0E8E66BB573B3D467B74B5493A4E8EA49A79B7E2D36A6C0A600C6B13DC617C3FAF927B2CB251279CFF4228254CB6022AE9D97A36894EBCB305B179284E5D2F330266B2B600E248D3C4B8121A8D698183A38BFB5A40C5E85CB08EF0BFB0242E418D11DD648B9B84E072A70D3FBA8A9B0CEE05BFD71AC945543E306824F9A4DCBA05BBE0027B475A020BD764B53AA5A187C089A2DEF8F3A96D38491A61CE5F3DA625F7F4EF38130B0F5DAA14E2236F4CD95FF0C31E7D6C1CC15CDE7D9D4F95326AE721812458D413CD6C758671C9A85D10F7692CE31A600483F6444F45E74C45B7CF886E63D0158E19C0B87BE6CD9FC4B74D72CB004D3BD7ADF60E162F4967E5EF3BCA0AF2DD7ED1DDE4097B5BA250281DB7E46C22A25A49ABDB1B2D148710128DC1F1A18CD0D762A1D2EB5D5D602336EE3F0A0095592E938A79BDEE72CF801015AD5871A8D907298E13F960A1417FDFA87C3FE3DA9490B73B45326C3161D9DE6460E37208665FDC90CF894A0301198F5FAA5A315FC562B2837194662A58DA13065760571172D42306BB57ECCFA578E9C927C211A1F7C1983DE1AE1EAB0A264AFDC18CD56F14E0429E80B0DDE9A5AF527952A7B6ABECFCB64CBDA3C3E7A024FC5CA3B655FAF5A2787FDB22C1DD3160827C886A119FD2833DA87E60F18B6A969916D35F559BCEA40D6E5E53F84FA5C46DD5DD09D0802A21F64F00EA755F95234AF913DBFB380CC370754448E46EDFC7CCC";
+ char testResult[512] = "8D9D660D7BCAB705F14A90CB9A31F7B5206F9936E1B56F2489DA188A90C49CA3";
+
+ // Get an HMAC GOST R34.11-94 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_GOST)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-GOST_R-34.11-94_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now recreate the MAC in a single part operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate the MAC in a multiple part operation
+ shsmMac.wipe();
+
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Check if bad key is refused
+ osslMac[10] ^= 0x11;
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(!mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+}
+
+void GOSTTests::testHashKnownVector()
+{
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::GOST)) != NULL);
+
+ // Message to hash for test #1
+ ByteString msg = "6d65737361676520646967657374"; // "message digest"
+ ByteString expected = "bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0";
+ ByteString result;
+
+ // Test #1
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(msg));
+ CPPUNIT_ASSERT(hash->hashFinal(result));
+
+ CPPUNIT_ASSERT(result == expected);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ hash = NULL;
+}
+
+void GOSTTests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+
+ // Set domain parameters
+ ByteString curve = "06072a850302022301";
+ ECParameters* p = new ECParameters;
+ p->setEC(curve);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(gost->generateKeyPair(&kp, p));
+
+ GOSTPublicKey* pub = (GOSTPublicKey*) kp->getPublicKey();
+ GOSTPrivateKey* priv = (GOSTPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getQ().size() == 64);
+ CPPUNIT_ASSERT(priv->getD().size() == 32);
+
+ gost->recycleParameters(p);
+ gost->recycleKeyPair(kp);
+}
+
+void GOSTTests::testSerialisation()
+{
+ // Get GOST R 34.10-2001 params-A domain parameters
+ ECParameters* p = new ECParameters;
+ p->setEC(ByteString("06072a850302022301"));
+
+ // Serialise the parameters
+ ByteString serialisedParams = p->serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dEC;
+
+ CPPUNIT_ASSERT(gost->reconstructParameters(&dEC, serialisedParams));
+
+ CPPUNIT_ASSERT(dEC->areOfType(ECParameters::type));
+
+ ECParameters* ddEC = (ECParameters*) dEC;
+
+ CPPUNIT_ASSERT(p->getEC() == ddEC->getEC());
+
+ // Generate a key-pair
+ AsymmetricKeyPair* kp;
+
+ CPPUNIT_ASSERT(gost->generateKeyPair(&kp, dEC));
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(gost->reconstructKeyPair(&dKP, serialisedKP));
+
+ // Check the deserialised key-pair
+ GOSTPrivateKey* privKey = (GOSTPrivateKey*) kp->getPrivateKey();
+ GOSTPublicKey* pubKey = (GOSTPublicKey*) kp->getPublicKey();
+
+ GOSTPrivateKey* dPrivKey = (GOSTPrivateKey*) dKP->getPrivateKey();
+ GOSTPublicKey* dPubKey = (GOSTPublicKey*) dKP->getPublicKey();
+
+ CPPUNIT_ASSERT(privKey->getD() == dPrivKey->getD());
+ CPPUNIT_ASSERT(pubKey->getQ() == dPubKey->getQ());
+
+ gost->recycleParameters(p);
+ gost->recycleParameters(dEC);
+ gost->recycleKeyPair(kp);
+ gost->recycleKeyPair(dKP);
+}
+
+void GOSTTests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+ ECParameters *p;
+ ByteString curve = "06072a850302022301";
+
+ // Get parameters
+ p = new ECParameters;
+ CPPUNIT_ASSERT(p != NULL);
+ p->setEC(curve);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(gost->generateKeyPair(&kp, p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+ CPPUNIT_ASSERT(rng != NULL);
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Sign the data
+ ByteString sig;
+ CPPUNIT_ASSERT(gost->sign(kp->getPrivateKey(), dataToSign, sig, AsymMech::GOST_GOST));
+
+ // And verify it
+ CPPUNIT_ASSERT(gost->verify(kp->getPublicKey(), dataToSign, sig, AsymMech::GOST_GOST));
+
+ gost->recycleKeyPair(kp);
+ gost->recycleParameters(p);
+}
+
+void GOSTTests::testSignVerifyKnownVector()
+{
+ // TODO
+}
+#endif
diff --git a/SoftHSMv2/src/lib/crypto/test/GOSTTests.h b/SoftHSMv2/src/lib/crypto/test/GOSTTests.h
new file mode 100644
index 0000000..f243392
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/GOSTTests.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ GOSTTests.h
+
+ Contains test cases to test the GOST implementations
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_HASHTESTS_H
+#define _SOFTHSM_V2_HASHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+#include "HashAlgorithm.h"
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+class GOSTTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(GOSTTests);
+ CPPUNIT_TEST(testHash);
+ CPPUNIT_TEST(testHmac);
+ CPPUNIT_TEST(testHashKnownVector);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testHash();
+ void testHmac();
+ void testHashKnownVector();
+ void testKeyGeneration();
+ void testSerialisation();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+
+ void setUp();
+ void tearDown();
+
+private:
+ HashAlgorithm* hash;
+
+ MacAlgorithm* mac;
+
+ AsymmetricAlgorithm* gost;
+
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_HASHTESTS_H
diff --git a/SoftHSMv2/src/lib/crypto/test/HashTests.cpp b/SoftHSMv2/src/lib/crypto/test/HashTests.cpp
new file mode 100644
index 0000000..f02adbc
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/HashTests.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ HashTests.cpp
+
+ Contains test cases to test the hash implementations
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "HashTests.h"
+#include "CryptoFactory.h"
+#include <stdio.h>
+#include "HashAlgorithm.h"
+#include "RNG.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HashTests);
+
+void HashTests::setUp()
+{
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::tearDown()
+{
+ if (hash != NULL)
+ {
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+ }
+
+ fflush(stdout);
+}
+
+#ifndef WITH_FIPS
+void HashTests::testMD5()
+{
+ char testData[4096] = "EDB39CC3CB5E8FD23A2182FAE8781F4E8E8534C8FE10BDC7ACDB34C4E22E4B60872E51AD092950771E475FB97B05D6203A0D1B3326D9678E44FB40787D8CF16BD3BBE4D4786F60BD8E9766EF1C30B22301FA8F7232358B3C5BE644342499622A5153B29D2E5F8F509771E8A5DE3B3737D30F2AB035262B8D83EC55F683E9B62BBB31E2E1F5E142A13ACB9701E1DE8752ACD492A943C2DB57CF4035BDA9D0519B86847CF74DB2F43CC23016D88EF44BA422710C00AEBB2ABDDED89D92E4BD132CEB87581644198B0D4AF82F3CE161ED03A4E189BE8276243243817F91159BDE294E61400041537618703754C609709846C3EDAE6922B498D24FDC6B9AE702A034BB3A2C6C230E58EE5759DC84AD0B960B111153F6D619E850E36833A26689B4718719EFF3A407B77B0BAD24A17E29B6A29E9125B4CF0DFFEB8D0B03D533ADA43D1F20CFFE0A067E0F6FFF28510148DD72AE33D8B72227523497B84082B682A480FA3B2FE42AAFF49883DAA4DC6826C9593D38002D73FA7AA91B41E828CC34FF12ECC1452B73709696A440CCDF3E6116DA36CB7A01C9E168C3518304721D2CDBC077F4D4B7E8D1A59F954872862F72AC12CB16E33BED8EC3CFD912E36BBF4DA86E31F5F45BE9294550965C7CBC03518AD7C5637A97F7470EDD6E359E82815230CE03AEE9512939A214D017719E5F6B2487E3B468D50DC8EA41EEE94360E77E0EAA9C27DFE2C28D63B7699406E2E6620FE23F96584EEA04034270A2A44096B70017CC2CB197CE8DA3B1924D8D2E86FB40FF59CCFC78B3A4F543068F08C3406DEF52413F95B2BE2AD5DA1ADBB7D95F2133F61AD5518A1BEA018E3C3C0C154EAE56B0B0F4A8818AE47DC618D138245192D055CE4EF8BD1A75030EABAFD66E45B204BA6B123FF54D78F51B6A7DB9B08BEE93E923F9DE553EC0BE4B8BE222998BC792002005ED66C0218902E7DDF6C6D5043A8A9790E438D5BDE37791CDC0DB6C974638884270D4F379DF845281C5F1F8A20978086A9444779D59423B6CEF8175E0BC2C517FA921EC66BE3F11ECEE078553F610D5B65FD293E37717C0CB323A2760646AD56C77A4B96940CF5AD1154A642043E40788C2D367123399FA6015422F5EFEC851EF558ACD4BC31EF3D3EF912241A586E54B97FAE083EE45FBBBED74BC9E3887795FC2EBC5354ACA358EC509F4AB8B2967488D5E5B77DD44EB72E66694A1F490ADEB2848918531B6FA7216C51CDB507598F1AA0985626482D3546BEF5CA3BB409934D11AECBAD47389F2CBCD85FB4DD1A8A6F4D0C28920671A31FFC14FC00FC51296A6182D5A05B16B33232798F0993C78BCC662932E2F57626D639DD00E39B206C1F8A15A19B5DCA9F8B015611AFA47A10A30527F552A22574E15E3577EAD9C7B89782F82D7082D747B50CEFD38C6F17D6269A696F518EE6EAFE1E1EA96FB4D";
+ char testResult[512] = "7299FE513582D71A3B9EA1E9F45F95FD";
+
+ // Get a MD5 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::MD5)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+#endif
+
+void HashTests::testSHA1()
+{
+ char testData[4096] = "0583243FDEDEBF8C9EA4017808B490A2581A5A06B8C2CCA4F2259B7FABDE4BECA9F80C3EFBFEC436CF5F252568CDF55C7D31002456F6FE711D404F9A274037E8D55EC6C55077E4900EEAF6524C44FBFCC1C5C1C6AF962CE22106610A7C8DE7D725BF924B81EA566B952C8723E0EAFA21EB2C6E6F5528A89FC24C478C0600CB4FD482FAFF8507284C5F1E8AEBA9CDBFB3E71D77B775DD7C09E65049423BBAA70499450AE3B46703A4A44AE281C1F0341EDF0473B079C44E0F9EFB4C3683ED706E480C901A16E77B52030A7E46E31991131AED9C98DCA1850A4BD6F35DBCF5A894A8843EE656EF0DC617D923EB38426855FAA2E77E70CE9A8AC81D0F14259A748F9227F732420CDAE5A1CFEA9B541F0B12ADD5D966EBF66613D7FBAF5FFCAC8D625CFA536DBCA8E54B01B237211656F165A8114CD157E82870BCCE6AE8AF5334105B4E50B0A4E4AE5D0A3CC5CD8FF85F7C4D20D2627694B168CB48DB81B5B78C620C7559B2043C268F5D7351256D41FE892ED8EF6F7B5DD8E193EDCD268C55C209DCD0E827FCF76D6951CEBD0065826FBF044ED5818FEE4ECB99973FDB6826BF92488652E804C40D07D4CE43FCB31481667EE637721B91FD38331A98A6E8969D5B1D0690CFA0B500D72BF2D42AD6471FE064496C91126EFCC46B8CD093BCBB70D21FDE1937A888CA08DF3068A858280ABEAF71608BC9229E8E5EFF1814C4887E3A26782A110F347560DAB6B07DB8D063E8343A3FCD99B34C3C3F649096339CA7D39DA6F7B2E489A9EE6CE01C923D45C50350AC57247838E323F1B2A284606E45D60938A6F492545C5EBA0C7396702C0F4E77F36AC9ECE7ADD32FA4EEF7B38F9FF3F8BFB4E05F1025AAB52FB1B4777A4FC4B881EFA484D04397DE4312B7EE2BCEAD0ABAC0513D9C1819F59996AB5E94D48C098634D9907A4CA41B5A900F7CC299937B089A52C221333BF6B35242CA8D552A9CAA3BB18944D5CCEF69E752FA74A8BA3DD58159BAE375944B26A636457C30C451A58984BD6F028C8CBD3ED893ECD2F1536AFF3A97DB92C0E2FC93B9CC3837FDF56E4E3065D10B15F9A5A8925A5F772E4521CDC885180ACE49D98719BCE6770604C11E6DF090C199A5BBF1D695E1D55E2C9E135E89AB26446F6FED3FBD7DFE58EB75CA61B2D3DA4974908C7183E62FDD79C233387C78EDFF8AAC412EA36AD929808023EF04B8C9B7F980CC3FFD50E7356F51FBDC3DE8551C4F5B283D41E861E5604155E81748BF017268D4FBA8D253CA695300F5FB9A51190B24E2B17653519A3FE500B27DFF90A9FDF8404AFA8FAA1C4F738EB45969846E0A18693C06CA5FE2F2B5F7A33974A9453383E558317468B47DDAEE7A2AB90AA2446155CBF5B6473628C1D6BDA9044D4D96D1E3846AA7A65046C680BB173670FC04E5AC7D8CF41C6F233BD6945C0EA90958E9DBFE67D0EBCD";
+ char testResult[512] = "9A5BD96DC0CD3B0089FBB6BE7D56BEE638431F5A";
+
+ // Get a SHA1 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA1)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA224()
+{
+ char testData[4096] = "8F300FA699500CA5E1E22B38EC06B2EADCE7738CF6A55CB241577D53ED68BD017517C83AEB9CD3A25536FE999B7CD61D9E2BA85C39A7D27CE2CAAC8FE7C12FA1B2905DB85ABF230A813C1A72D2BD93BE0C5A79842FE35C5EF4B2E94524FB9594E3CCC63FE2A4E21D91C25DED832FE8BC9788697051C2042094585187394BD0AFD64FB627F3CCB350874FD0D454BF0254A72DD99ED211F68DC15B94A5682B73B89BF533746E8EEC5CCE45DF55466D7026A95A062EFD49FA270751A8D427095D38FB757FD4D1395B5DC7D302D9CF28C2E2D09796B9E0FC2D1F56BDE005FCD266B097822C170981DE2DB5E92582A612019823A3A062E228AB99AD6A0E47C1DEAC0078460252D83FA11253A3EFD374B2B392F0E27079F9FCACBB8EE6320C7A06327335AB34B757057E6C7FEC5004C4F675D2C4ACC6B359CC13D6F9FBE7E12EA7F6FF753CA8FB68059DB06D9804CBE08AAA55E0F20EFB7094695C1BF0D8E504EAD0836C0E6BB491E1691FDEB9ADFE0C92CED19A612DBCA01FF5A515E32B4EC06BDA00482DE721B6A85F00CAB264B34C5F3749D35603D0216C5AA426BBFF15637D1AE7805ACA572337232C27BDFC9D17D5D129242FD883E3C33250BA089EA03BD794C03D8DB9F57F87DC0A30E37F063B9C4C43518DC9F94E7BB18718D1DC79474CFAF60CBCD5CAA8AAA9FF573E26BB8B722C522ACF561FF34A0716FB7C1217050AD6E8323889B47D7551BC7554909651A9BAFCF5F0FEFD100D35B2E06D89C46E572E3EB5A07FEA702DF10BBCD2CAF2F2A62A9BC162F6369D0DBD9A6D6368ECDAFF4246DEE682C2B20EF4D7BBCCABBE0CD44CFBB531F2190E55C1A650B4D16DB2DA0453B23C4F056C1F791336A7266742976653B2E9377F500AAEFA1EA5FEE3469F4A85A484F69FBFFC1C163F78872AFB79231D9E5B4F8EFE2A9E8487BC33E4EC462F9E451BFEB306964D1F02873EEABCAB0F06361DD463398717537C7C255E3DEF1E9EC1567A600CFEB63F822A3C24B3524225A40F0CE948B0284AEF1F9BBE7618D18839725087DD6BFEE15653B981D6F57ED6685388F3B510140F437E93B92583609D4B873BBA3641B2DB56AB26D3DC27A85866D8F66C4A33D82932ECE277387E583BB20A689BE12B597C6199799A3A53B970596355A46F7F94B9D5E07B09B8C47355CE19D7D2EC1F1DA8F382F7C90ABABDED1D82C8BD673C008E16102025B8C8AD33832953B9E28A1C01353C513D55F4E38C0FBC1FE7C1FB6B93D10B464F851BFE26426BC09C599708CA1CA3413BC4B147CD69A761E688E3846949AC3F455CCDC0DDB4FDBC91D880B38C73B7AD4C8633598F4570E3BCBA3C5E785686E38D2926187CDF0479DF5B818EBDDFDA757C31DF009ED234B3C0F2BC1ADC700FD715AFEE46AE5CBAD02ED086912BE45BE2D61097F008E45067C4ADC4FDFE29220E6CF0C6F7F8";
+ char testResult[512] = "A4E71A239CED53E936011DF80B516A07DFF13BB5B05BE43C46C05CCD";
+
+ // Get a SHA224 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA224)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA256()
+{
+ char testData[4096] = "C75FF0C53CB345524BF9800FDF53CE448F3369F9CA08C817F8F07AEF0689274527F0AF1EE7FB5AE99B37456765F39880640BF6C5582111753758DF49A9A13B52379DA0C7AE930B03BC57CD819D2EBA0E38AD33D10876608B99A69D0A73F001065276055C4B659F62F77E7232B021BC085A2472293D2D1875028444902AB29D78C9919EC52B33C9F839B1F839C7FF39B68669C925F53AFC865C93D3694E2FD3F29FF0B7773BB412D0FDB1B506A4D501F840D01AE9BF18D7558109B10A6E55CD8CF9A5279D559810A0B08C84C2C8C294AFEC06C6219EB1647A51488BCDDAACE7C652BB0D3F1DC552E4B42BAFF52FD17239F4C08DDDA1BBA97D8D35D3A3DA32D66858B2D320A62AAA7C3909C3A34DCF9DAA69BEC13B7B3EAAEA8A56E2C6DB2507C43BE8990ADC4A281B8BFC6C76FAED50217F109594902FF7E0EDFF5C018B0FC76CACFF84FB9EA97D6D543EDA732089E82FDE3B9D087320014680E5EA2B21B534125806B650F3268DB7951460A9E32F2EEAAF69300E6F0B7F846ECBC2904E93E8D0423FBDCC3E34C5085A97636EA9961B00880BC381E37C3A6E3115256B1A9E1A915A401A8E507F97A09BF3881E852FEA614DF76D709DE6DC0FE54500E0C42132E9ACFFE4A4A98654190FC6C14FC3E5F42CDCCAE0DE05DEF5F6961D7D13DE15376F35142C5846013B7D4A8A6AB363EC7932415C556B83787C86491820AA29C2FE31E39A3D73D710C490D1AF863C4166C2301ECF6967506DCFF6F97CAE63245634153072FE27E9C4B5F90B3C42E4BDB4FB0E85A548CDE2D3B480ABFB1ED6F054017B120E41529909AC055A9F5A29E25D0E5D1A8E8550B9C85C300BBAAE030B22BB646B1FD3A90FA1C242A26071423B3E239EF65BE8B347663B6BF63436AFFD311D10FD24C8E8D05CA99A808C41E6C9C7B283FE5FE9E311642349D2799B6D0CACD5826CC6CC5DDA22FB8BBDD6C66BB722697E4558A75B6D24FDD55631C17FCB591CA3CBA180CEC241B0555A91DF4D47A648A7D901B02C1AB557C4E1CF33E277AFE008D586857203FD6CE695C8EDD446F74056B173D6A0B07A2A58B39366B58BB76AF96DF9C37A5A5E1F8419163CEAA304D451DC38B8F142C422FB475869667D55D88F7C2624FC0B29A958BB4A44C6B0439542AAB02319D46B7E482149DC9A7C7BEBE651C7E8404140601CDB3742F58B6EEDA137FA083BA9D297F91B41B34C3535230841F18B672ED0FD817B7E4E3CD1FC018CDA63C21C3C3ED68228DF85B8C26572D1B14EF10D5D0BAF6F3ED4B9A8C3DFEB4EDEA00CE2DB5903D510432BCBA791C1BBDD2770F2616AF855941E1BD710CEE4F17C4C7A9E283B12DE901A88D634E4ADE69ED529328D64F8069033A6B4DA5D8E0E1C0150DB862AAD54F2827B41CE1F21E3F890033FD46E438615DDC527D6D1260BDB79478D6A0BE2B58174648A2387E3AE";
+ char testResult[512] = "3902802C215A5271439FE3E81AC7F21DA55545F71193A8DA8BEB0EAC8046A43B";
+
+ // Get a SHA256 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA256)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA384()
+{
+ char testData[4096] = "11FCD8770F582C2D9C860D1EB4FDBFE40C551C6F3AF41A2540A39BA3A121BFEF995F1727A8703C29D0A44EB85B339F27955E1C679796A72980BB1D1BEF4D51A73174A983D36CDAD56BC1EEBA5DDD642094996531EEC94DE2FB6E0ED4F23BCB2F1D0B25505EB16306473DA17F809BD994FD9A737D29819BCCF94CA225D2EBB9D89DDA6E03E80A9DE87E44B72EFD397F9F344122B6591CED9BFDE8C0C42D8C17223A93F33B7D569291F91B619297F233C1454A168AAE126E89B0ED32B0B69AB095A1BB24BB7F1AAF8EE0BDBB43025EF3339F96C9EA352E78BA0661DE896E8F4DFAA7EF623F2B5305AD338448C5FCBDD6CC1F1222ED1D8F4C634B82591F8906DA8DDA9A0FFB0F1499B5BD08239F7EB3A02ACEC60FB76754D0AC5077C3B733D346F0BDE654CD612F60E2284115297A1557679901A911C2AC7323DA2FF3CD57895D7D181AD43AB7068609CE046B96B445EA08CDF50C40DFAFBA9F7082707A813B9C8E4E9D7F0230D5AFE40174693512DE96E3FAB1C8F6548880823645A0AD811694B293F788D0D523EBD81851594733EF45FC763B956044E29B29C195BDB317FBF97F41C601A2873C25557C3149F648424380FE79E4DC407A9CECD8F14B843C642FD9921F12786C8A1C6F8514C99672038693C5CF1FBE91F903E4ABC9E55B967B2F72FDF1A2EC09C14C94C001BAC47A0C36E9E6F34431381069CFD64D85F11285391A4DC7419B2EE8062F344538413E757EC258192B90F2CCC1186AB9A4ED5CE1290644CDEDAF03A4BF3E94B9F9D132ED159CE03586C5A69EF0A471146378BCCE799A3CD8D627B688BB28C9288F44D1218BC34A05BEAA398371ADC60CA8A2557AB69BE7B737F84BFFA93A1E1115F498600F52144E0D61055A2FC0CD45E20962CB2FF475896D733C74C2E95986389ED74B1497A35E73FEE0F36270CC65D76C1FE27A35E8F1FA0C5CA7F2C6003E21BD6677502CE268EB55B16DA863FA291AA111F338F10592AF86DFC297718365C04839748195E20A64BF42020846A46C94F1728549B8310A7FBCBA2C1441B033639CE52B6DBDA69F6ACC57F2DE6BAC57755734AFE4B77869C4D9B0DC56B115476A86A82F816CB148CDFD2B1DCCBEFCD4559B59AA88C6429F4A9EBB43B641144752A5E6F8BE1B739AA69FEBCB8D7439E5D917CA759982146E627FF81E80CEBC37BE0CF2A6C12A3E84A389FFD25013C491AE90A395D4DBCA81340E86848217AC426603CCAC981B5ED701CE9AB2851DC5F2ED72484FE99767C0FDB6F122B0C67926A637B57EC4F047804BC3A9BD55CBD78B83154BC27B6F8A66085EF02A206F329F3B1531ED657C75E29DF4276070AE5054F484A12990A9DD13C112FB6D3D57AE42E6A048870FDAABA48F73E03344C0E13832BAFCA2AF81AF19E5C28983F7BAAA5135803E78FBDDF7FB53C9B9B709274F05C774C77F0B84";
+ char testResult[512] = "753659D55E4198325A3FED0A35761EC45038E8963B7525BF00D5A6A5D904DD9FA3FC80AB020185E08B14992ECC36A744";
+
+ // Get a SHA384 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA384)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
+
+void HashTests::testSHA512()
+{
+ char testData[4096] = "B9D5BD978E1B4A0268331AE4F0C4494EBA71125ED75B9B4244407271A29D93BF5BA0D6641EBF7A210A0905B5EBE675F7B900B89542D0DA6A3952DF9DC5430ECE31F4A5834CCF132724963A088DE43966DC9F46011F2AD458E8FCDBA18F6D183235687A6145401E9FA2EDF60F47F3835D953B5856B1F8308457D9CEC29246DC51F5B42BD5DE38BD89945667579C05756D1C47BB58C2C3D049C58C014C1F6D962BF5EBA1D273F5A7FD6D9291E293CD30B8D8B489E79E54A7A11953EAF4FB6AC7F99910ECE05B511E098B6AD33A599F5A8FA43692FDD9F2A26F316427A2ED1F231E328864CDF9BA2879E0A711F48038E653520C74B7EEA8858F17AC332B87EF4C70A838263C8B17B373161A5A15293D1A7991F0EEAAE0BB69C95DEC22A1CD6808122489703770B5E276735F9D149067A7F3E6A7D10A790253C81778BB79C06D1F98A2CA9C2E8C4BAC0A96F0F9736B85E7BB4F090C5BEB25F087AC037517A9599D94E072D03D9C48665DD17649E001E45966AB8F2C7D24E38AE4F0519F056B034E0ED2CA133F108105BE4823758543791225144AB0B9609F0F861B69EEA8707D6DB9046910F28C6F8E1D47F59DFE9B59F81242FCBE5A71669B90F7B4050E517CF6D3F2FB8759FB7300F12C786D36183FA64692F379D030D0EA90859D9D8E00F27500B41FD716E325E695E3D8EBB40A4E32AFA75F6F21013C8A3261E9C18291DC99142FFF91EAB6C2B55FF5DE03B1DCC88C79635B96F13B66CE6E26A1D5F6154F3C6E5F22AF4B0334FD4521AE57B6B13E2D3B777AF66742635740ED4FF5FC752B908A079A6BBE8499344096549E6FC6FEDBE57AAF2992E7CBB19931F43360415C39D65D2A92775C78DE97C712022460E48651EBDDB9E0527C7EE59F6C817499100C11E884633DC66EF85B176D7A529894CA8F364F559D97DC7CF1769813FB36F8F738E77354C14A560CB98DF92BB5BB16A5A3EDFB75CB78A718C070BE5D37A6F742F88B51BC633FA9E309311BCA908F4D5EE381FB593B7A53E4CE3A529160A2965D0C4CEDC6548D036A1A4FE4576DA9D35E0CDDE9567E792D5C77EFAC17E531F402E0BE99957A7D378E90C009F3231FEE6E3898B5D2C4291EAD396CA748AB0A39469B921BDC5F8066AB7F0D28EE0C502EBC95C2A39DB4241886736F17DE1F33BD384EFDEA951BF775A0D41A499E85D0488016D7A281A9F7C715EBB7CD6AFBA59C1A93A5AEA66D71C3058C5A293141EE4D2C3E65853EFBEFC55912F5C08B9990A66C313F3199C0769CDCA711E877766ECA773EF2FDBC0656B8427CA6442062D911B13F1C2E92D3F0C608B1D8F12914953720021D5648364F953F93CC49946E44FBAF154A2FE3A8055922F784FF9B56D5FAC35B65266A248794101C12750DB8C107D048E551E52EB3952CFA26345B4E21652F5F3B8F85DE04AF9731B75C79DDBD6FE1A5";
+ char testResult[512] = "E1483A8525CE39705D14D60D8B19BD89087AED5FE6D8913AF8FC3F6F4EA2C1BB5957E205294B1EFAF20AE5EE39A9522F38B4514C3C15ED70BCBBD5821E385F95";
+
+ // Get a SHA512 hash instance
+ CPPUNIT_ASSERT((hash = CryptoFactory::i()->getHashAlgorithm(HashAlgo::SHA512)) != NULL);
+
+ ByteString b(testData);
+ ByteString osslHash(testResult), shsmHash;
+
+ // Now recreate the hash using our implementation in a single operation
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ // Now recreate the hash in a multiple part operation
+ shsmHash.wipe();
+
+ CPPUNIT_ASSERT(hash->hashInit());
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(hash->hashUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(hash->hashFinal(shsmHash));
+
+ CPPUNIT_ASSERT(osslHash == shsmHash);
+
+ CryptoFactory::i()->recycleHashAlgorithm(hash);
+
+ hash = NULL;
+ rng = NULL;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/HashTests.h b/SoftHSMv2/src/lib/crypto/test/HashTests.h
new file mode 100644
index 0000000..dd6566d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/HashTests.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ HashTests.h
+
+ Contains test cases to test the hash implementations
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_HASHTESTS_H
+#define _SOFTHSM_V2_HASHTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "HashAlgorithm.h"
+#include "RNG.h"
+
+class HashTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(HashTests);
+#ifndef WITH_FIPS
+ CPPUNIT_TEST(testMD5);
+#endif
+ CPPUNIT_TEST(testSHA1);
+ CPPUNIT_TEST(testSHA224);
+ CPPUNIT_TEST(testSHA256);
+ CPPUNIT_TEST(testSHA384);
+ CPPUNIT_TEST(testSHA512);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+#ifndef WITH_FIPS
+ void testMD5();
+#endif
+ void testSHA1();
+ void testSHA224();
+ void testSHA256();
+ void testSHA384();
+ void testSHA512();
+
+ void setUp();
+ void tearDown();
+
+private:
+ HashAlgorithm* hash;
+
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_HASHTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/MacTests.cpp b/SoftHSMv2/src/lib/crypto/test/MacTests.cpp
new file mode 100644
index 0000000..8a3db1e
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/MacTests.cpp
@@ -0,0 +1,687 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ MacTests.cpp
+
+ Contains test cases to test the MAC implementations
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "MacTests.h"
+#include "CryptoFactory.h"
+#include <stdio.h>
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(MacTests);
+
+void MacTests::setUp()
+{
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::tearDown()
+{
+ if (mac != NULL)
+ {
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+ }
+
+ fflush(stdout);
+}
+
+#ifndef WITH_FIPS
+void MacTests::testHMACMD5()
+{
+ char testData[4096] = "B64CCFF0DC038F4B4B6C77677B1E89774028CFB6F94EE920ABFABC8C389F7DE287D558664FD05836E854458940A486A367C9B771A7938BE7DFFF2C695BB99CB96F946707FB405A0FA94116FC4002FAD47F813C4DAF6F39B579A2C1E607AF0F80E55FC6742ABB46CF25EFBAEF820DACAE925532E0F2AAAD64D23D0E5682DC38FA47F230EAA299C4D87EB76D45D4B4A08BB47AC873A428708F9D236CF9B11831BC713DB5C8F58A4A4DD228B7A370154CCDB92420B01D0B4141B2CBF05E51D364F7A4D7EE20F1299A697AEAE7341EB6C2F5C458D8AA9A33CE6B2C87B42A9C8EABB3A3311E3828935B8743604895A37D0E9717266872B51CBAB50E9399A0E54457F88DB022CD1859D704FE07C2B530BE14A11072133A9D3A8CD94FCA2B22A320EA08D0292DEADAC4BF705B2CDF71CDC13EC72918F2BD8697BA42AA0AAD62E2D549AC639095EFD2EF606414207CD3770A14FA14AAD7EED197A1A61EBF1FCA89CFE2B69E709C98F4299CF6E1DCF34A98F3C89C6357B5DCDCB335C98EA8DBBA64700EFF9B79CCB875FA49C0C8FA8AA98D6B7B83C3818C4078A8433EEEC71423D9B476029C190ECF1552CF59E1BB2ACDB08663FA792D806E5FF5A6D3E4E09C3F6276663A09D5730A9AAB456D4863F2EDEFEF156A7809AA16D3202AA03C64359BAC628EA1D9ABE2D99999C2891ED49C6081DEA6907C93C5873B4D7880DE271D6016075AFF330FDF221790258A99564F1B51B979DE7997F5FD6676F679B4B14222753547C06960ADCC287EDC29E627FB88BD0E73EBC4E631A58DCA425FADFFEE9DBA177EC182CABA803EEE16636599A88C39A828A5FB206F6DDFD6023F560A421FF3D93B6C4A2A27B78283280C2FD5D249C35270EAE8F8947FA07189BB3A03184C1D8DDB12038184C467EE7DA6CD62F1775F316BE3C2FAB947D49DA19B480E8E4CB4C7818D7769351107386311E5EE411DAC5136869C147DA8E782FA60ED69B13C2DE18CF11FD75CE5F8F16993A026FC3441EE3B23DD6002B8F015E5CC336B5559A427864338C098F4857AA40399916614E061BB176AE4457CA72625A37F08F179A14C39B065CF3283E9425355B6504784C0F4FC1D7932F5C14B43A9CE3604935DE695CDB60B1ED58BD71AB540EEDDF9337B0743D8E624E1A932A69FB1FCA21CFE7F6D2FFDA78F2B8D5BCE01C59BC0A3981BB3BBECF345F43ACD571432B742F80491B490FD71F947480FF9D215EC21237F5AF28C31608DA7A6230CAD24EA799506C8C0B1298E9FD09DA496C6B63710920CC0DC14C00944A7D9B9B751D741A828AB35A5926D3653D45531A4D233DE198439D1946633FF6B91DF0744073CC6E3EC3B177414D8ED2AF30515D8688914667F507667776634A2A11BB68F65B363BD56E8CCF957EB4BB0147862D4C17268AFCE5685C8346E1917B8E8618D3888355CE401AAC5D2DF";
+ char testResult[512] = "1026862877813E17E4371095271E1B56";
+
+ // Get a HMAC-MD5 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_MD5)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-MD5_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate the MAC in a multiple part operation
+ shsmMac.wipe();
+
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+#endif
+
+void MacTests::testHMACSHA1()
+{
+ char testData[4096] = "EA9E200DE69522895F516F1380536406D205D72B31ACB902CC582B12696579826B5AF47892C4831D8AEBBAE039D87F82096364782B49E2E896AB8077E773AB61E05A8223BF17CBF37AB1BDDA70C9B10D9943AF4109571ECFB029156889249B309EC45A34E2D701F1F4093610A7064B69E7FAE5FB39E39EEF3CAA9D64E50DA8822DF4C8DFA064B165ECA4C9CD2A6AF1A251A1F5D4004123B67A7CC3FAB7462AD43535018479BDFD24A2C4A1C4271F907E40E2057A6271BB2BC9740F753CA3692E7ACACE547E64B9FAE79A96DF3DDFCDA7FDCCC7612E41B0B9BBFA3BDE2102F322E8EC42DA2679531782920FD2E7385F6AC887D578B9D844F6A7288EDF613F3663EB538DBFF14EA29AC8D2F58C703303CD370F55BAF02532A0BCB2F80673F6D84B04A5C3EF9E05B640B4CFFD903272089B9960B54197CB5D10C23BAFEA72EFF79C65E0EABEC628EEB5850AC4A23DC80E857EBA5EC5EDB9DD0A5F391B7F8BD354EC976881C157BD5735AD894F020164A9DF214150C5788BC1CF73C15437DBF21D791C75074DF4B51B5C0ABDC79063AB7B7CEDEDC6412F9FB1F6CA171BE6814E033F32CF1F08236A3DD657DB96CCF7A35434C4D0ACFCA81546B4138A6EF6987A874111946010F78074E69BA83E3F395D1C239A122B259F48140E4B80157738A5D443E1762C55EBB67791D5297B3E900B0B53CA7433FB61D2D03C3B34772C5DF77711437003C6DFF4B03DC0B713491F526F9AE3260F903EF9A1BED641E1B262103D395ACAC3FE6F6F1436F0CB3A13AC69C60101EC394DAFFCAD8EED23893C4BC30485FC68854447A9930C0F4FB9AC5B72EF6512278F09F5A024C7CF5C5617461751CE193E54051AE93DF136725642E1DB98842BAA8B8F6231181F0BAA8393FC2EDB7CF0832BA1FDB76A46C8059732B7492711AD1A12BA584D49885E263789E27664B3893EF2DE5C010C093DE1A735D806E4D48C36A0995EADF011FB50D0CA97AFF26B4698524B9F75386897940434A0A38EAF513845BF0F024014001180C651F76B9E0ECA6499F177A1079395C1785B856D5762550EAD2B47B15AF0A6BFBB1B597E72B9E5E6F61769C27AFC29E4D8A523C89D1D2E5E59B57DE89BE04BDC1DCDA0476A157BCB4DA2F7AC0CAF9351772652E2E5B6261501BDF42C23EA9726CB6C258EE9511684CFEECA1C0598D372808002E250EDD4019F85630FD499C35016B8A99C6BF78E69053B4AE7BE6B84009B505594603B363037212DAFCC669F7482995C74A7CC225245DC2E7D4CACC8A59F67513E1D788F0218DA902F440CD2FEB6C2A90A653B0C2DBE45CC67B47863C1090F3F41AFEA9C53CE5C61A7E6B7212EE3BBE67ED91EB1BA006A931055512046779935F84D7CA306C7F9F3894F91F51EFF6005F5A8BD9DD8828BCEA1C4CC6E5F22CE7F14C0A942243C1205FD7697F09C333AE0B263";
+ char testResult[512] = "C2FFE4BF83A6FE299CA4A187157F2442EC1527CE";
+
+ // Get a HMAC-SHA1 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA1)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA1_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now recreate the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate a wrong MAC
+ b[5] ^= 0x28;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac != shsmMac);
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA224()
+{
+ char testData[4096] = "83E369A9F34D645B7E1F2F7BB676A4DFD36C411D5472A9AC6F3945EF5C9A561BB040C38F2F321C582882820C7F44D48CDC5BB84F41818F4AEB226F63078CE131481D26F26C61EE52BD1BFB60EDEDE1E03A8656E87D5662EE0C0AE085E56E488325512467DAC43E99484A16FA419D6704922C1ADE06F7D1188DBEC88384CDBFDCD2E74787AE247A8027EF60383B3B0A7D0D3ADA95BB3AA5F0821AF050A9709C75673F3926CF9AE029158D684F470DE3EE6B00BBC90F85CD6E634E86B67E4D8EB4251B472B02D167790C6E6C38BA9FE39880544EA66EB4C0BFF8AFEB9AFC40ADC24DF191744482F70793CB4A802CF1AB58562CC26D1CAA2E80375BA45507C3E9F7D99223E0E7FE93CAC58B7B0C69231162D2D7DA75EEFD59452642CDC5AA4A118B6D4AD00E8368A44988201C6286CAA8612BCFFF714855DE1E053AFD2EEED9737459540E45AEAB26999C0951228716AF02F0D35264E3411B03D222F331A4695D6DF4E9EE35D5B1015FF0BE46081D7CEC9137824217A711F015639BE76223845F1C2A25A10D29B637C5124CF50AB0CAA1E33D75843D00EAE69C3A189D463377731C3197BF44523936C4F84F143759E3D58891F7B3B51C858EE29BC1DF214AF09C93148172E842A7FC0078D4E106324AAF8862B845F290FE831037B2EFEF2528DF070DD7B1ACD67762CF1071B96FB95C5AA14F7AE13103AF45A1CF3C42C5D53CB5B954F97BA223E70E0098E224BEF8F5430D027B510DFBBC35EE5F9170E4A43BDDFCBAE8B82240DB870B6C7C7E21E21234EFA62F1582A9D150CCE1B8822BD77ED8288B20883AAEEB5BDF9D0EBB8D3FF47DD51B99E9BDB8B8A87D0536CC25D4939ECB13F7B4F7DF5F0BE8231CF3F53CE52D16A29825739B26BA4082975583967180F787ECF98AD956A9CE53759E20960752938C142DF80E57DDCA236A1F596031942016442002683865EDB210073797547D83CE77D3D6C39E2B9034E685BD28D365992E821BECAFC6DF2B60EAE9777FEE7879B176CC602501BA0B0BCB434DFA5517F8D6172647364F235B3C9BA0B1B90FE0FD67CF6650C2D8D2BC08D127DF0AB887F69CDD81D03B4CC7F44A4362C90BB38556D081E51EABD9CA3AA6C877C42FD1B001C030D0B281590696B5BB9C6A78CBE356F7AC72F525300FD13E24755294712DDF48D1AD19F844120306DC99D8CC18516A23BD022CF9DC9CACC168ADDE1C15337F15B3FBEDE4BFA498F2F963E14B7E66CD737A5485227BA1BAA7668D97C58DCE40EE7A843A5E6EB591FF91D6A6292C8A3E95A0B23C1F0B8815BE526EE7C49B5153264BC1207013EA85E9DA37F19BD50DDC9F0A5B9AB4FCFFAD2840B5A8856882E8DF95362DCA13C15328137A2A8318884FCF4D05236CEE9985DB1BA873A9AF5B33E317FA2C0CB94E7C18E46744A374C19D8C9B2788FE50C9E4D237D290555E1077";
+ char testResult[512] = "4B089658FF932CA07BF7C42E6EC46BFF560BCAF295826D9D3C0BAE1C";
+
+ // Get a HMAC-SHA224 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA224)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA224_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now don't verify a MAC with different input
+ b[600] ^= 0xff;
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(!mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA256()
+{
+ char testData[4096] = "FF7E669D7764FABF6E3550E192E660DF1EE237B49F9473D757DEFA1400534F57C81E8B0E99458F74E6F57A5BB71A50D1EF61EDB3B3FB4BCA57896DFBA50C6C55B04D4C8C804DB8EB2A273E25F49AE2742D2AE430BE9A3A07715AF6816E818B63BB1FF8C876A921CF931F693E624CDAD4B54F3ABBEE4A09BF39E0FE3A313B20CD3A36B0EBD677D9D4D7C576B5EA244CF0436110D9D66110C95BE187D6EDA1E81A4456231BE32A1B5F4CDC02B2DA679322AEBAE0B795763888F07F0222ADBF824F31AEC7B80625DC36DA1F0C3DD20C6E8F79A7FA2D286119894E611EE550364428723E9C33A573F18D02F9DC90ED215EF08C95DB1CED68DA864732BC9A56B8B191815BCC12075641E3E87F46EFD3726BC1D6F47AF7BC573C554279C041C7FD5E924093241855507EE2A837E2CE62E7A9898712EDF593217B6425B3EB855D53D31F38E5A0736E34844AFCAD58A15B06D357697DC921C2FCA77091BFC207B0B4F1FA94F923B05817211462104287B43CA72986D9E6E393C9A075C267B2C1706CAD136E9F549A83E58315DE8D0B67852006EFE8B6E0773519FE6DB316EA596E1998B79C19152AADDDF8E025E7EDCB16B5CCBA2C9F990605A6969D3C667D6EDA1DA5AFF476661349712CD73F707BB0FD6F8BF0C13A90DE9C1C5CE9FB696C22849C1205C8435C818E2EE03F2235B502E0C24068B8687AF9ED065910535072DABB83F651FC60E005BEF909F6EE308B37E43DA01366C062168007D733D5EA4A610D1307BA087E8F883864140BBB02E523997A0D83E9BF289B8EC9F83F57FF553485409B0D82E77F32BD2D06A130103B9F3915730EE8BC3FB099B74AE8B32C478A83D0BAD2281C279D6B802F42A80E179F4ABB69AD485BBAE348C6F774285870F53699500CEC045B9521CF22826FAFFBC4EABE9D856B28DDBC6D2A0F318AE9475E82DE2CA6704B743397EFE45F825019B58D9E671181512D780B1BA34D059BFBF8B9B232E337335C1045682635CEF8D3CB1C744D3A7791F5DB323EF8DE768C63931266EAB0DFACAB0F99BC9C5DA234FE48ECDB23A5FDA2E92EC10AF7476B07C4BB85BDD0600B49F41585F9E0DB2B276BBE0FA7C5792B65012B6564561E4814E8D1EE706935A45F969C9AA110A630E354C7243E21436A180046605FE5D31008045A5C4AB4FF5C23585D77D6C839875CC2E960436A3D90F9664D5522EAB08867B95F9641DF0C81D59DCA8ECE8709A3F521532041BDCF7A7535F940BD3569FD2145A1B34E955E04F66E0CA809BA3FA6A347FD0CB69DADBA93DC03CDF547A96CD3159ACA61EFE20F9A566316BB9C746EB851CE51F04823667CDA0D898253BB10C1C5220B2C30461A49C5FF0DEC38264786C6125720B3768629ADABCF694E01795F618FBD0ADE5C91CB5A981BBA581A9664F51DF758D7300E081E57CE20C8A7210BC3558AD240B7";
+ char testResult[512] = "90A49F8EB80D8ED405EFC8D658FCB9102314598939DCAA090756668056B0228A";
+
+ // Get a HMAC-SHA256 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA256)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA256_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult);
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Check if bad key is refused
+ osslMac[10] ^= 0x11;
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(!mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA384()
+{
+ char testData[4096] = "7D4C4274CFAFABE3605DE7E35B43F10251A441A6F4B03EE142B9EAE3DEC2E30E1A47FBE779D716427B108CCB2A2C2D7561B879B1C021E00E0498D91859BA3E7851EF3FC25A1BC6EADA8524EAEEDCC0E752AD90DFD0EA2F04B71B8ABF56DA85E4D070C91EC4B7723A02C3B52DAE31EEAF8E397CC3E92FA31E5F3292D8C9F45D459D8D1105E539D3979ADC01EB4E0C90BC33351295628BD0C2E1B4B13764EDD66BE9AD67AA7B4A7780264B0A3DBE099B190D25649B692401E0B758AB2A281B2E1AC9B4F7EE051C1B98BE92463F314A86A7FD40A4683A82457699F514563C70F1231C0B667C7B8CAD5910334CF894A9810D7C7C6DFC1E904D8512813A84911580C2AC56BB005A4FFB512A1290501AE795C832C0BF7DEBCD9B1D84CC0BB5B5F19D02FDBAB01F7B7CA47C99F3CB7D4F0D35622C267EBDADB2D089D0DA73FEA15A25C873C27EF72A84F99EC4E6980695BA6468B34B5AEC0746219468FEE88277739123FB51CEBF264140FFF27B94D6F751F26F0BC27387A2EFD038EEE43013AFC8FE94BE8E272B28ABFE2160BA81416113CBC2A1ADD96DD23F7107F4771CF2016501A8918A9A71C476CEDC10BB355BC144C818FD620301793CB16372A80881C5DFE387619ED651626CF44C8EDA8DA5BA8A6895148EE36037D4ADDBC13C5681935EDC5BD9B35F8E91B84C1F593B3E89614879CAE4DF4413E13655079F3CE21449CCA19E0963C925A75BC294F343016518D2F8FCB13ED38D574232602AD2416E94ED7735680439CE042145552F352156FCA722B31BFAA289C3711F170A845143ADFEF49CA53278358A7FECBD605AE9899192990D728CA37218B65DD9978EC4345100E174F3D04A0C8A5611263DABF7DA0BC6CE50BCD338830688B697FEB71909D1A2E09B62C5C4A8C1069C50C8DD6A432ED2B429F6BBFC304D0F0A35167BBDDCBC7F78959058393BC812820AF4917C56EA9233A1567608534F93857EA783B537CE294B4778E4B5D30D5836AE1F0D25B663A62512D2488E959D7FF000F8A70F31CC4CABB51D6F57A842AEABD707122935690F78F1F8BD7EC8544F1E70B9D6D53C50632F4DF5F0BC75630B427B28BAF2249C72F5864A3CE17627BA4F16F8FF13FA19DDF83736B171C024C95EFBC5D90615C495C2B02685C24C6E64E19C804B1DC138B5BC52A6969C4332F6113ED8C38F03A0107513C611A6FF013D2FC0B00859A6A5DFB8626002EA0126D477B5F9C7B5BEAB61A13AA8841A4C11E9DFB6A7164BBC2D40E940D9D10C56D58FBC76B92EA68425C2FF48BAE0CA2AF6F1CFBFFBBD855688C3960538E2D87088472CD73AB6D0FB86D9411310F5311EFCA3B89949A87D408B86B96C29C89A0180AF8957944E2A385A221081870CECC995FFDDD6994B0856ED0DC6303F7FDE5072F0B3D68BB132B0C5D3113939D614677720186052F4F90DD60A1CFD";
+ char testResult[512] = "AC387A4BB1E4E078C43C69087C206F49F56EC63CE244A429DA56B8EC3CAFBC987090DA7A8F6470874CA6049D20AC5154";
+
+ // Get a HMAC-SHA384 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA384)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA384_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult), shsmMac;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate the MAC in a multiple part operation
+ shsmMac.wipe();
+
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac == shsmMac);
+
+ // Now recreate a different MAC
+ b[100] ^= 0x42;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+
+ CPPUNIT_ASSERT(osslMac != shsmMac);
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testHMACSHA512()
+{
+ char testData[4096] = "A7A3B0B40CBAAB9B58F6946D9D15870B56E6832DECB708949EBF98DC4EC9C0AF477216C542A98A3646B6ABB72D89E6B3F18201CC75E93B37C2E8EADAD6827FBBFFD220642A92CABB587B27590ED204F8B2C926777C3DC9E5273CBB38582C103905C074002DAA2D8D16DD907BEFB4C51B49C464FF22B93269274291D1254889E3F677FBA6929AF472AECC02DECF822EABB2F05311E0BA8600B58075D4E49837F81C9565E37EAC96B9C2F3C08E3D818DD507D0CC8064C8CC7553D5A17204F4B92B74E5A441CF9142ED059DB1ADA76C799B10178FB3E76E4E3CAC6B1AD8648D522DCA6C93200E706D947E15422E1CC47742CCBF8E2C1E50492AFFA49BE22D5E34B0ACA62744626E2EF7014EAB17D8E538324D9A764501428A53593D23E3785831C1262F220883E2DEEFC66584A3AEC1F35998F842C5298A5E28653CF40F21C6E2383086C266E2902272198D45B38308904F5D2F614A6857E027D133C5455E75B16B9DB124755ADF06B16F04872D74D1A90F36709D8263B1190D625849F017930763AC1EA548DEC56BFD46D09F32D6ABAE96A778B39FBF22B1D6B3CA43F8E7ED32DB2254018FB1999ED0C4C3CDE710899CB20AB5E1CA706DA3E4E8E65253782379B49B7DEFE4E26DD498A935057E91B8FFB8B110336A554A6C61C26C2DDEEE8631926F8A706171B309B99E3B24030C17609340EBB82C4129B172B64CE6249FED00F05DCD624969BC1E4A29ED028C9821A812CDC310A974B959B29E30888887D9A8688E92F85E2A1683C5E993BCC584979F0B3F7DBE34295E2D852B6444EC4152A0C40F3113B402027E323231FC2EDD8078D6661F598588F68FB83DE9C2CA1491107E1F7B676BE16AA6C62B2FF86056905CFCE1FA57065B20A87B15BF1EADAC5FD94F5368451CE8CC2D363BC184A6E87D3D088CBCDE259845E4046D314660B1C1D4AFC7CCC37C7B1B8BBC7A54B63FE61FCD082966425AC3795F08BE7AFD6F9C66F2C3C50DD1EB6B8F8FC3C1A6A298A442EB6FC14AA906A7DA7854B53205E0A8F91C8D6CC3C41F4795FA70E14BA876548022733E61972F0351BC4187FFDE18E776BD68C5E947D2F0B19206D34770BA8ED63874639BBCEAA8D59771A02AEE654D20C69ACD8D16C42BAED6BD1AC51134F49C2A1D685B045527D4A86A7656439A2587F48F5AC43C5094DC680ECE19EBDD53B39F3B84F36D363D8CE464A20DE7ED50C6E32D5C7A9C3868D9823DF0E0A5FD824D239F67C41BC5AD3615AB51EA8B1A2C50B6D4C8F196F1278D9747B8C0B941509850052E63467950EBCE7B56D5E5C481D39E3958C51AE1267C075D8E62EC7F15400A5B4B91B15789015FBCCCC8186DC888CC0BC70326F1800FF56B01BC39DD1C2421BE6E142627B24822790DA36AD9CEA0661FAA03074FAA6F9EBC243DDCB249334B13D31DC19C0F03C6923CBFFEC6FAA29255";
+ char testResult[512] = "93E3A4336693965FEEC902F3BDDB064DD63D83EA1E46AA13DA209F8F000C15F366D3F9BE4F8AF189EA96D191D0BDE4CF0FC6C462C214B55ABF78F33BD6DF3DD0";
+
+ // Get a HMAC-SHA512 instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::HMAC_SHA512)) != NULL);
+
+ // Key
+ char pk[] = "a_key_for_HMAC-SHA512_test";
+ ByteString k((unsigned char *)pk, sizeof(pk));
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+
+ ByteString b(testData);
+ ByteString osslMac(testResult);
+
+ // Now verify the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, 567)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567, 989)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(567 + 989)));
+ CPPUNIT_ASSERT(mac->verifyFinal(osslMac));
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACDES2()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[33] = "4cf15134a2850dd58a3d10ba80570d38";
+ char testData[4][2][256] = {
+ {
+ "",
+ "bd2ebf9a3ba00361"
+ },
+ {
+ "6bc1bee22e409f96",
+ "4ff2ab813c53ce83"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a57",
+ "62dd1b471902bd4e"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51",
+ "31b1e431dabc4eb8"
+ }
+ };
+
+ // Get a CMAC-DES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_DES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(112);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACDES3()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[49] = "8aa83bf8cbda10620bc1bf19fbb6cd58bc313d4a371ca8b5";
+ char testData[4][2][256] = {
+ {
+ "",
+ "b7a688e122ffaf95"
+ },
+ {
+ "6bc1bee22e409f96",
+ "8e8f293136283797"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a57",
+ "743ddbe0ce2dc2ed"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51",
+ "33e6b1092400eae5"
+ }
+ };
+
+ // Get a CMAC-DES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_DES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(168);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACAES128()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[33] = "2b7e151628aed2a6abf7158809cf4f3c";
+ char testData[4][2][256] = {
+ {
+ "",
+ "bb1d6929e95937287fa37d129b756746"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172a",
+ "070a16b46b4d4144f79bdd9dd04a287c"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
+ "dfa66747de9ae63030ca32611497c827"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+ "51f0bebf7e3b9d92fc49741779363cfe"
+ }
+ };
+
+ // Get a CMAC-AES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_AES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(128);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACAES192()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[49] = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b";
+ char testData[4][2][256] = {
+ {
+ "",
+ "d17ddf46adaacde531cac483de7a9367"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172a",
+ "9e99a7bf31e710900662f65e617c5184"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
+ "8a1de5be2eb31aad089a82e6ee908b0e"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+ "a1d5df0eed790f794d77589659f39a11"
+ }
+ };
+
+ // Get a CMAC-AES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_AES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(192);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
+
+void MacTests::testCMACAES256()
+{
+ // Test vectors from NIST SP 800-38B
+ char pk[65] = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4";
+ char testData[4][2][256] = {
+ {
+ "",
+ "028962f61b7bf89efc6b551f4667d983"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172a",
+ "28a7023f452e8f82bd4bf28d8c37c35c"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411",
+ "aaf3d8f1de5640c232f5b169b9c911e6"
+ },
+ {
+ "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
+ "e1992190549f6ed5696a2c056c315410"
+ }
+ };
+
+ // Get a CMAC-AES instance
+ CPPUNIT_ASSERT((mac = CryptoFactory::i()->getMacAlgorithm(MacAlgo::CMAC_AES)) != NULL);
+
+ // Key
+ ByteString k(pk);
+ SymmetricKey key;
+ CPPUNIT_ASSERT(key.setKeyBits(k));
+ key.setBitLen(256);
+
+ for (int i = 0; i < 4; i++)
+ {
+ ByteString b(testData[i][0]);
+ ByteString nistMac(testData[i][1]);
+ ByteString shsmMac;
+ size_t size, part1, part2;
+
+ // Now recreate the MAC using our implementation in a single operation
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a single operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+
+ // Now sign the MAC in a multiple part operation
+ shsmMac.wipe();
+ size = b.size();
+ part1 = size / 2;
+ part2 = size - part1;
+ CPPUNIT_ASSERT(mac->signInit(&key));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->signUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->signFinal(shsmMac));
+ CPPUNIT_ASSERT(nistMac == shsmMac);
+
+ // Now verify the MAC in a multiple part operation
+ CPPUNIT_ASSERT(mac->verifyInit(&key));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(0, part1)));
+ CPPUNIT_ASSERT(mac->verifyUpdate(b.substr(part2)));
+ CPPUNIT_ASSERT(mac->verifyFinal(nistMac));
+ }
+
+ CryptoFactory::i()->recycleMacAlgorithm(mac);
+
+ mac = NULL;
+ rng = NULL;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/MacTests.h b/SoftHSMv2/src/lib/crypto/test/MacTests.h
new file mode 100644
index 0000000..9e6fa99
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/MacTests.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ MacTests.h
+
+ Contains test cases to test the MAC implementations
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_MACTESTS_H
+#define _SOFTHSM_V2_MACTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "MacAlgorithm.h"
+#include "RNG.h"
+
+class MacTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(MacTests);
+#ifndef WITH_FIPS
+ CPPUNIT_TEST(testHMACMD5);
+#endif
+ CPPUNIT_TEST(testHMACSHA1);
+ CPPUNIT_TEST(testHMACSHA224);
+ CPPUNIT_TEST(testHMACSHA256);
+ CPPUNIT_TEST(testHMACSHA384);
+ CPPUNIT_TEST(testHMACSHA512);
+ CPPUNIT_TEST(testCMACDES2);
+ CPPUNIT_TEST(testCMACDES3);
+ CPPUNIT_TEST(testCMACAES128);
+ CPPUNIT_TEST(testCMACAES192);
+ CPPUNIT_TEST(testCMACAES256);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+#ifndef WITH_FIPS
+ void testHMACMD5();
+#endif
+ void testHMACSHA1();
+ void testHMACSHA224();
+ void testHMACSHA256();
+ void testHMACSHA384();
+ void testHMACSHA512();
+ void testCMACDES2();
+ void testCMACDES3();
+ void testCMACAES128();
+ void testCMACAES192();
+ void testCMACAES256();
+
+ void setUp();
+ void tearDown();
+
+private:
+ MacAlgorithm* mac;
+
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_MACTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/Makefile.am b/SoftHSMv2/src/lib/crypto/test/Makefile.am
new file mode 100644
index 0000000..bf63ae6
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/Makefile.am
@@ -0,0 +1,39 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+AM_CPPFLAGS = -I$(srcdir)/.. \
+ -I$(srcdir)/../.. \
+ -I$(srcdir)/../../common \
+ -I$(srcdir)/../../data_mgr \
+ -I$(srcdir)/../../object_store \
+ -I$(srcdir)/../../pkcs11 \
+ -I$(srcdir)/../../session_mgr \
+ -I$(srcdir)/../../slot_mgr \
+ @CPPUNIT_CFLAGS@ \
+ @CRYPTO_INCLUDES@
+
+check_PROGRAMS = cryptotest
+
+cryptotest_SOURCES = cryptotest.cpp \
+ AESTests.cpp \
+ DESTests.cpp \
+ DHTests.cpp \
+ DSATests.cpp \
+ ECDHTests.cpp \
+ ECDSATests.cpp \
+ GOSTTests.cpp \
+ HashTests.cpp \
+ MacTests.cpp \
+ RNGTests.cpp \
+ RSATests.cpp \
+ chisq.c \
+ ent.c \
+ iso8859.c \
+ randtest.c
+
+cryptotest_LDADD = ../../libsofthsm_convarch.la
+
+cryptotest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install
+
+TESTS = cryptotest
+
+EXTRA_DIST = $(srcdir)/*.h
diff --git a/SoftHSMv2/src/lib/crypto/test/RNGTests.cpp b/SoftHSMv2/src/lib/crypto/test/RNGTests.cpp
new file mode 100644
index 0000000..da793b5
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RNGTests.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RNGTests.cpp
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include "RNGTests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "ent.h"
+#include <stdio.h>
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RNGTests);
+
+void RNGTests::setUp()
+{
+ rng = NULL;
+
+ rng = CryptoFactory::i()->getRNG();
+
+ // Check the RNG
+ CPPUNIT_ASSERT(rng != NULL);
+}
+
+void RNGTests::tearDown()
+{
+ fflush(stdout);
+}
+
+void RNGTests::testSimpleComparison()
+{
+ ByteString a,b;
+
+ CPPUNIT_ASSERT(rng->generateRandom(a, 256));
+ CPPUNIT_ASSERT(rng->generateRandom(b, 256));
+ CPPUNIT_ASSERT(a.size() == 256);
+ CPPUNIT_ASSERT(b.size() == 256);
+ CPPUNIT_ASSERT(a != b);
+}
+
+void RNGTests::testEnt()
+{
+ ByteString a;
+ double entropy, chiProbability, arithMean, montePi, serialCorrelation;
+
+ // Generate 10MB of random data
+ CPPUNIT_ASSERT(rng->generateRandom(a, 10*1024*1024));
+
+ // Perform entropy tests
+ doEnt(a.byte_str(), a.size(), &entropy, &chiProbability, &arithMean, &montePi, &serialCorrelation);
+
+ // Check entropy
+ CPPUNIT_ASSERT(entropy >= 7.999);
+ CPPUNIT_ASSERT((arithMean >= 127.4) && (arithMean <= 127.6));
+ CPPUNIT_ASSERT(serialCorrelation <= 0.001);
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/test/RNGTests.h b/SoftHSMv2/src/lib/crypto/test/RNGTests.h
new file mode 100644
index 0000000..1391d81
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RNGTests.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RNGTests.h
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RNGTESTS_H
+#define _SOFTHSM_V2_RNGTESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "RNG.h"
+
+class RNGTests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(RNGTests);
+ CPPUNIT_TEST(testSimpleComparison);
+ CPPUNIT_TEST(testEnt);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testSimpleComparison();
+ void testEnt();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // RNG instance
+ RNG* rng;
+};
+
+#endif // !_SOFTHSM_V2_RNGTESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/RSATests.cpp b/SoftHSMv2/src/lib/crypto/test/RSATests.cpp
new file mode 100644
index 0000000..6af1e19
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RSATests.cpp
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSATests.cpp
+
+ Contains test cases to test the RNG class
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vector>
+#include <cppunit/extensions/HelperMacros.h>
+#include "RSATests.h"
+#include "CryptoFactory.h"
+#include "RNG.h"
+#include "AsymmetricKeyPair.h"
+#include "AsymmetricAlgorithm.h"
+#include "RSAParameters.h"
+#include "RSAPublicKey.h"
+#include "RSAPrivateKey.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RSATests);
+
+void RSATests::setUp()
+{
+ rsa = NULL;
+
+ rsa = CryptoFactory::i()->getAsymmetricAlgorithm(AsymAlgo::RSA);
+
+ // Check the RSA object
+ CPPUNIT_ASSERT(rsa != NULL);
+}
+
+void RSATests::tearDown()
+{
+ if (rsa != NULL)
+ {
+ CryptoFactory::i()->recycleAsymmetricAlgorithm(rsa);
+ }
+
+ fflush(stdout);
+}
+
+void RSATests::testKeyGeneration()
+{
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ // Public exponents to test
+ std::vector<ByteString> exponents;
+ exponents.push_back("010001");
+ exponents.push_back("03");
+ exponents.push_back("0B");
+ exponents.push_back("11");
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+#ifndef WITH_FIPS
+ keySizes.push_back(1025);
+#endif
+ keySizes.push_back(1280);
+ keySizes.push_back(2048);
+ //keySizes.push_back(4096);
+
+ for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
+ {
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ p.setE(*e);
+ p.setBitLength(*k);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+
+ RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
+ RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getBitLength() == *k);
+ CPPUNIT_ASSERT(priv->getBitLength() == *k);
+ CPPUNIT_ASSERT(pub->getE() == *e);
+ CPPUNIT_ASSERT(priv->getE() == *e);
+
+ rsa->recycleKeyPair(kp);
+ }
+ }
+}
+
+void RSATests::testSerialisation()
+{
+ // Generate a 1024-bit key-pair for testing
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ p.setE("010001");
+ p.setBitLength(1024);
+
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ // Serialise the parameters
+ ByteString serialisedParams = p.serialise();
+
+ // Deserialise the parameters
+ AsymmetricParameters* dP;
+
+ CPPUNIT_ASSERT(rsa->reconstructParameters(&dP, serialisedParams));
+ CPPUNIT_ASSERT(dP->areOfType(RSAParameters::type));
+
+ RSAParameters* ddP = (RSAParameters*) dP;
+
+ CPPUNIT_ASSERT(p.getE() == ddP->getE());
+ CPPUNIT_ASSERT(p.getBitLength() == ddP->getBitLength());
+ rsa->recycleParameters(dP);
+
+ // Serialise the key-pair
+ ByteString serialisedKP = kp->serialise();
+
+ CPPUNIT_ASSERT(serialisedKP.size() != 0);
+
+ // Deserialise the key-pair
+ AsymmetricKeyPair* dKP;
+
+ CPPUNIT_ASSERT(rsa->reconstructKeyPair(&dKP, serialisedKP));
+ CPPUNIT_ASSERT(serialisedKP.size() == 0);
+ CPPUNIT_ASSERT(dKP != NULL);
+
+ RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
+ RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
+
+ RSAPublicKey* dPub = (RSAPublicKey*) dKP->getPublicKey();
+ RSAPrivateKey* dPriv = (RSAPrivateKey*) dKP->getPrivateKey();
+
+ CPPUNIT_ASSERT(pub->getN() == dPub->getN());
+ CPPUNIT_ASSERT(pub->getE() == dPub->getE());
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
+ CPPUNIT_ASSERT(priv->getPQ() == dPriv->getPQ());
+ CPPUNIT_ASSERT(priv->getDP1() == dPriv->getDP1());
+ CPPUNIT_ASSERT(priv->getDQ1() == dPriv->getDQ1());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+ CPPUNIT_ASSERT(priv->getN() == dPriv->getN());
+ CPPUNIT_ASSERT(priv->getE() == dPriv->getE());
+
+ // Serialise and deserialise the public key
+ ByteString serialisedPub = pub->serialise();
+
+ RSAPublicKey* desPub;
+
+ CPPUNIT_ASSERT(rsa->reconstructPublicKey((PublicKey**) &desPub, serialisedPub));
+ CPPUNIT_ASSERT(serialisedPub.size() == 0);
+ CPPUNIT_ASSERT(desPub != NULL);
+
+ CPPUNIT_ASSERT(pub->getN() == desPub->getN());
+ CPPUNIT_ASSERT(pub->getE() == desPub->getE());
+
+ // Serialise and deserialise the private key
+ ByteString serialisedPriv = priv->serialise();
+
+ RSAPrivateKey* desPriv;
+
+ CPPUNIT_ASSERT(rsa->reconstructPrivateKey((PrivateKey**) &desPriv, serialisedPriv));
+ CPPUNIT_ASSERT(serialisedPriv.size() == 0);
+ CPPUNIT_ASSERT(desPriv != NULL);
+
+ CPPUNIT_ASSERT(priv->getP() == desPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == desPriv->getQ());
+ CPPUNIT_ASSERT(priv->getPQ() == desPriv->getPQ());
+ CPPUNIT_ASSERT(priv->getDP1() == desPriv->getDP1());
+ CPPUNIT_ASSERT(priv->getDQ1() == desPriv->getDQ1());
+ CPPUNIT_ASSERT(priv->getD() == desPriv->getD());
+ CPPUNIT_ASSERT(priv->getN() == desPriv->getN());
+ CPPUNIT_ASSERT(priv->getE() == desPriv->getE());
+
+ rsa->recycleKeyPair(kp);
+ rsa->recycleKeyPair(dKP);
+ rsa->recyclePublicKey(desPub);
+ rsa->recyclePrivateKey(desPriv);
+}
+
+void RSATests::testPKCS8()
+{
+ // Generate a 1024-bit key-pair for testing
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ p.setE("010001");
+ p.setBitLength(1024);
+
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+ CPPUNIT_ASSERT(kp != NULL);
+
+ RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
+ CPPUNIT_ASSERT(priv != NULL);
+
+ // Encode and decode the private key
+ ByteString pkcs8 = priv->PKCS8Encode();
+ CPPUNIT_ASSERT(pkcs8.size() != 0);
+
+ RSAPrivateKey* dPriv = (RSAPrivateKey*) rsa->newPrivateKey();
+ CPPUNIT_ASSERT(dPriv != NULL);
+
+ CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));
+
+ CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
+ CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
+ CPPUNIT_ASSERT(priv->getPQ() == dPriv->getPQ());
+ CPPUNIT_ASSERT(priv->getDP1() == dPriv->getDP1());
+ CPPUNIT_ASSERT(priv->getDQ1() == dPriv->getDQ1());
+ CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
+ CPPUNIT_ASSERT(priv->getN() == dPriv->getN());
+ CPPUNIT_ASSERT(priv->getE() == dPriv->getE());
+
+ rsa->recycleKeyPair(kp);
+ rsa->recyclePrivateKey(dPriv);
+}
+
+void RSATests::testSigningVerifying()
+{
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ // Public exponents to test
+ std::vector<ByteString> exponents;
+ exponents.push_back("010001");
+ exponents.push_back("03");
+ exponents.push_back("0B");
+ exponents.push_back("11");
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+ keySizes.push_back(1280);
+ keySizes.push_back(2048);
+ //keySizes.push_back(4096);
+
+ // Mechanisms to test
+ std::vector<AsymMech::Type> mechanisms;
+#ifndef WITH_FIPS
+ mechanisms.push_back(AsymMech::RSA_MD5_PKCS);
+#endif
+ mechanisms.push_back(AsymMech::RSA_SHA1_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA224_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA256_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA384_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA512_PKCS);
+ mechanisms.push_back(AsymMech::RSA_SHA1_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA224_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA256_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA384_PKCS_PSS);
+ mechanisms.push_back(AsymMech::RSA_SHA512_PKCS_PSS);
+#ifndef WITH_FIPS
+ mechanisms.push_back(AsymMech::RSA_SSL);
+#endif
+
+ /* Max salt length for SHA512 and 1024-bit RSA is 62 bytes */
+ RSA_PKCS_PSS_PARAMS pssParams[] = {
+ { HashAlgo::SHA1, AsymRSAMGF::MGF1_SHA1, 20 },
+ { HashAlgo::SHA224, AsymRSAMGF::MGF1_SHA224, 0 },
+ { HashAlgo::SHA256, AsymRSAMGF::MGF1_SHA256, 0 },
+ { HashAlgo::SHA384, AsymRSAMGF::MGF1_SHA384, 48 },
+ { HashAlgo::SHA512, AsymRSAMGF::MGF1_SHA512, 62 }
+ };
+
+ for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
+ {
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ p.setE(*e);
+ p.setBitLength(*k);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+
+ // Generate some data to sign
+ ByteString dataToSign;
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));
+
+ // Test mechanisms that perform internal hashing
+ for (std::vector<AsymMech::Type>::iterator m = mechanisms.begin(); m != mechanisms.end(); m++)
+ {
+ ByteString blockSignature, singlePartSignature;
+ void* param = NULL;
+ size_t paramLen = 0;
+ bool isPSS = false;
+
+ switch (*m)
+ {
+ case AsymMech::RSA_SHA1_PKCS_PSS:
+ param = &pssParams[0];
+ paramLen = sizeof(pssParams[0]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA224_PKCS_PSS:
+ param = &pssParams[1];
+ paramLen = sizeof(pssParams[1]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA256_PKCS_PSS:
+ param = &pssParams[2];
+ paramLen = sizeof(pssParams[2]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA384_PKCS_PSS:
+ param = &pssParams[3];
+ paramLen = sizeof(pssParams[3]);
+ isPSS = true;
+ break;
+ case AsymMech::RSA_SHA512_PKCS_PSS:
+ param = &pssParams[4];
+ paramLen = sizeof(pssParams[4]);
+ isPSS = true;
+ break;
+ default:
+ break;
+ }
+
+ // Sign the data in blocks
+ CPPUNIT_ASSERT(rsa->signInit(kp->getPrivateKey(), *m, param, paramLen));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(0, 134)));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(134, 289)));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(134 + 289)));
+ CPPUNIT_ASSERT(rsa->signFinal(blockSignature));
+
+ // Sign the data in one pass
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, singlePartSignature, *m, param, paramLen));
+
+ // If it is not a PSS signature, check if the two signatures match
+ if (!isPSS)
+ {
+ // Check if the two signatures match
+ CPPUNIT_ASSERT(blockSignature == singlePartSignature);
+ }
+
+ // Now perform multi-pass verification
+ CPPUNIT_ASSERT(rsa->verifyInit(kp->getPublicKey(), *m, param, paramLen));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(0, 125)));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(125, 247)));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(125 + 247)));
+ CPPUNIT_ASSERT(rsa->verifyFinal(blockSignature));
+
+ // And single-pass verification
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, singlePartSignature, *m, param, paramLen));
+ }
+
+ // Test mechanisms that do not perform internal hashing
+
+ // Test PKCS #1 signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 35));
+
+ // Sign the data
+ ByteString signature;
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS));
+
+ // Verify the signature
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS));
+
+ // Test raw RSA signing
+ size_t byteSize = *k >> 3;
+
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, byteSize));
+
+ // Strip the topmost bit
+ dataToSign[0] &= 0x7F;
+
+ // Sign the data
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA));
+
+ // Verify the signature
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA));
+
+#ifdef WITH_RAW_PSS
+ // Test raw (SHA1) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 20));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[0], sizeof(pssParams[0])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[0], sizeof(pssParams[0])));
+
+ // Test raw (SHA224) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 28));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[1], sizeof(pssParams[1])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[1], sizeof(pssParams[1])));
+
+ // Test raw (SHA256) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 32));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[2], sizeof(pssParams[2])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[2], sizeof(pssParams[2])));
+
+ // Test raw (SHA384) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 48));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[3], sizeof(pssParams[3])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[3], sizeof(pssParams[3])));
+
+ // Test raw (SHA512) PKCS PSS signing
+ CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 64));
+ CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[4], sizeof(pssParams[4])));
+ CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[4], sizeof(pssParams[4])));
+#endif
+
+ rsa->recycleKeyPair(kp);
+ }
+ }
+}
+
+void RSATests::testSignVerifyKnownVector()
+{
+ // These test vectors were taken from the Crypto++ set of test vectors
+ // Crypto++ can be downloaded from www.cryptopp.com
+
+#ifndef WITH_FIPS
+ RSAPublicKey* pubKey1 = (RSAPublicKey*) rsa->newPublicKey();
+ RSAPublicKey* pubKey2 = (RSAPublicKey*) rsa->newPublicKey();
+#endif
+ RSAPublicKey* pubKey3 = (RSAPublicKey*) rsa->newPublicKey();
+#ifndef WITH_FIPS
+ RSAPrivateKey* privKey1_1 = (RSAPrivateKey*) rsa->newPrivateKey();
+ RSAPrivateKey* privKey1_2 = (RSAPrivateKey*) rsa->newPrivateKey();
+ RSAPrivateKey* privKey2_1 = (RSAPrivateKey*) rsa->newPrivateKey();
+ RSAPrivateKey* privKey2_2 = (RSAPrivateKey*) rsa->newPrivateKey();
+#endif
+ RSAPrivateKey* privKey3 = (RSAPrivateKey*) rsa->newPrivateKey();
+
+#ifndef WITH_FIPS
+ // Reconstruct public and private key #1
+ ByteString n1 = "0A66791DC6988168DE7AB77419BB7FB0C001C62710270075142942E19A8D8C51D053B3E3782A1DE5DC5AF4EBE99468170114A1DFE67CDC9A9AF55D655620BBAB";
+ ByteString e1 = "010001";
+ ByteString d1 = "0123C5B61BA36EDB1D3679904199A89EA80C09B9122E1400C09ADCF7784676D01D23356A7D44D6BD8BD50E94BFC723FA87D8862B75177691C11D757692DF8881";
+ ByteString p1 = "33D48445C859E52340DE704BCDDA065FBB4058D740BD1D67D29E9C146C11CF61";
+ ByteString q1 = "335E8408866B0FD38DC7002D3F972C67389A65D5D8306566D5C4F2A5AA52628B";
+ ByteString dp11 = "045EC90071525325D3D46DB79695E9AFACC4523964360E02B119BAA366316241";
+ ByteString dq11 = "15EB327360C7B60D12E5E2D16BDCD97981D17FBA6B70DB13B20B436E24EADA59";
+ ByteString pq1 = "2CA6366D72781DFA24D34A9A24CBC2AE927A9958AF426563FF63FB11658A461D";
+
+ pubKey1->setN(n1);
+ pubKey1->setE(e1);
+ privKey1_1->setN(n1);
+ privKey1_1->setE(e1);
+ privKey1_1->setD(d1);
+ privKey1_1->setP(p1);
+ privKey1_1->setQ(q1);
+ privKey1_1->setDP1(dp11);
+ privKey1_1->setDQ1(dq11);
+ privKey1_1->setPQ(pq1);
+
+ // The same key but without CRT factors
+ privKey1_2->setN(n1);
+ privKey1_2->setE(e1);
+ privKey1_2->setD(d1);
+
+ // Reconstruct public and private key #2
+ ByteString n2 = "A885B6F851A8079AB8A281DB0297148511EE0D8C07C0D4AE6D6FED461488E0D41E3FF8F281B06A3240B5007A5C2AB4FB6BE8AF88F119DB998368DDDC9710ABED";
+ ByteString e2 = "010001";
+ ByteString d2 = "2B259D2CA3DF851EE891F6F4678BDDFD9A131C95D3305C63D2723B4A5B9C960F5EC8BB7DCDDBEBD8B6A38767D64AD451E9383E0891E4EE7506100481F2B49323";
+ ByteString p2 = "D7103CD676E39824E2BE50B8E6533FE7CB7484348E283802AD2B8D00C80D19DF";
+ ByteString q2 = "C89996DC169CEB3F227958275968804D4BE9FC4012C3219662F1A438C9950BB3";
+ ByteString dp12 = "5D8EA4C8AF83A70634D5920C3DB66D908AC3AF57A597FD75BC9BBB856181C185";
+ ByteString dq12 = "C598E54DAEC8ABC1E907769A6C2BD01653ED0C9960E1EDB7E186FDA922883A99";
+ ByteString pq2 = "7C6F27B5B51B78AD80FB36E700990CF307866F2943124CBD93D97C137794C104";
+
+ pubKey2->setN(n2);
+ pubKey2->setE(e2);
+ privKey2_1->setN(n2);
+ privKey2_1->setE(e2);
+ privKey2_1->setD(d2);
+ privKey2_1->setP(p2);
+ privKey2_1->setQ(q2);
+ privKey2_1->setDP1(dp12);
+ privKey2_1->setDQ1(dq12);
+ privKey2_1->setPQ(pq2);
+
+ // The same key but without CRT factors
+ privKey2_2->setN(n2);
+ privKey2_2->setE(e2);
+ privKey2_2->setD(d2);
+#endif
+
+ ByteString n3 = "A8D68ACD413C5E195D5EF04E1B4FAAF242365CB450196755E92E1215BA59802AAFBADBF2564DD550956ABB54F8B1C917844E5F36195D1088C600E07CADA5C080EDE679F50B3DE32CF4026E514542495C54B1903768791AAE9E36F082CD38E941ADA89BAECADA61AB0DD37AD536BCB0A0946271594836E92AB5517301D45176B5";
+ ByteString e3 = "03";
+ ByteString d3 = "1C23C1CCE034BA598F8FD2B7AF37F1D30B090F7362AEE68E5187ADAE49B9955C729F24A863B7A38D6E3C748E2972F6D940B7BA89043A2D6C2100256A1CF0F56A8CD35FC6EE205244876642F6F9C3820A3D9D2C8921DF7D82AAADCAF2D7334D398931DDBBA553190B3A416099F3AA07FD5B26214645A828419E122CFB857AD73B";
+ ByteString p3 = "C107a2fe924b76e206cb9bc4af2ab7008547c00846bf6d0680b3eac3ebcbd0c7fd7a54c2b9899b08f80cde1d3691eaaa2816b1eb11822d6be7beaf4e30977c49";
+ ByteString q3 = "DFEA984CE4307EAFC0D140C2BB82861E5DBAC4F8567CBC981D70440DD639492079031486315E305EB83E591C4A2E96064966F7C894C3CA351925B5CE82D8EF0D";
+
+ pubKey3->setN(n3);
+ pubKey3->setE(e3);
+ privKey3->setN(n3);
+ privKey3->setE(e3);
+ privKey3->setD(d3);
+ privKey3->setP(p3);
+ privKey3->setQ(q3);
+
+#ifndef WITH_FIPS
+ // Test with key #1
+ const char* testValue1 = "Everyone gets Friday off.";
+
+ ByteString dataToSign1((const unsigned char*) testValue1, strlen(testValue1));
+
+ ByteString expectedSignature1 = "0610761F95FFD1B8F29DA34212947EC2AA0E358866A722F03CC3C41487ADC604A48FF54F5C6BEDB9FB7BD59F82D6E55D8F3174BA361B2214B2D74E8825E04E81";
+ ByteString signature1_1;
+ ByteString signature1_2;
+
+ CPPUNIT_ASSERT(rsa->signInit(privKey1_1, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign1));
+ CPPUNIT_ASSERT(rsa->signFinal(signature1_1));
+
+#ifndef WITH_BOTAN
+ CPPUNIT_ASSERT(rsa->signInit(privKey1_2, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign1));
+ CPPUNIT_ASSERT(rsa->signFinal(signature1_2));
+
+ CPPUNIT_ASSERT(signature1_1 == signature1_2);
+#endif
+ CPPUNIT_ASSERT(signature1_1 == expectedSignature1);
+
+ CPPUNIT_ASSERT(rsa->verifyInit(pubKey1, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign1));
+ CPPUNIT_ASSERT(rsa->verifyFinal(expectedSignature1));
+
+ // Test with key #2
+ const char* testValue2 = "test";
+
+ ByteString dataToSign2((const unsigned char*) testValue2, strlen(testValue2));
+
+ ByteString expectedSignature2 = "A7E00CE4391F914D82158D9B732759808E25A1C6383FE87A5199157650D4296CF612E9FF809E686A0AF328238306E79965F6D0138138829D9A1A22764306F6CE";
+ ByteString signature2_1;
+ ByteString signature2_2;
+
+ CPPUNIT_ASSERT(rsa->signInit(privKey2_1, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign2));
+ CPPUNIT_ASSERT(rsa->signFinal(signature2_1));
+
+#ifndef WITH_BOTAN
+ CPPUNIT_ASSERT(rsa->signInit(privKey2_2, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign2));
+ CPPUNIT_ASSERT(rsa->signFinal(signature2_2));
+
+ CPPUNIT_ASSERT(signature2_1 == signature2_2);
+#endif
+ CPPUNIT_ASSERT(signature2_1 == expectedSignature2);
+
+ CPPUNIT_ASSERT(rsa->verifyInit(pubKey2, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign2));
+ CPPUNIT_ASSERT(rsa->verifyFinal(expectedSignature2));
+#endif
+
+ // Test with key #3
+ ByteString dataToSign3 = "D73829497CDDBE41B705FAAC50E7899FDB5A38BF3A459E536357029E64F8796BA47F4FE96BA5A8B9A4396746E2164F55A25368DDD0B9A5188C7AC3DA2D1F742286C3BDEE697F9D546A25EFCFE53191D743FCC6B47833D993D08804DAECA78FB9076C3C017F53E33A90305AF06220974D46BF19ED3C9B84EDBAE98B45A8771258";
+ ByteString expectedSignature3 = "175015BDA50ABE0FA7D39A8353885CA01BE3A7E7FCC55045744111362EE1914473A48DC537D956294B9E20A1EF661D58537ACDC8DE908FA050630FCC272E6D001045E6FDEED2D10531C8603334C2E8DB39E73E6D9665EE1343F9E4198302D2201B44E8E8D06B3EF49CEE6197582163A8490089CA654C0012FCE1BA6511089750";
+ ByteString signature3;
+
+ CPPUNIT_ASSERT(rsa->signInit(privKey3, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->signUpdate(dataToSign3));
+ CPPUNIT_ASSERT(rsa->signFinal(signature3));
+
+ CPPUNIT_ASSERT(signature3 == expectedSignature3);
+
+ CPPUNIT_ASSERT(rsa->verifyInit(pubKey3, AsymMech::RSA_SHA1_PKCS));
+ CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign3));
+ CPPUNIT_ASSERT(rsa->verifyFinal(expectedSignature3));
+
+#ifndef WITH_FIPS
+ rsa->recyclePublicKey(pubKey1);
+ rsa->recyclePublicKey(pubKey2);
+#endif
+ rsa->recyclePublicKey(pubKey3);
+#ifndef WITH_FIPS
+ rsa->recyclePrivateKey(privKey1_1);
+ rsa->recyclePrivateKey(privKey1_2);
+ rsa->recyclePrivateKey(privKey2_1);
+ rsa->recyclePrivateKey(privKey2_2);
+#endif
+ rsa->recyclePrivateKey(privKey3);
+}
+
+void RSATests::testEncryptDecrypt()
+{
+ AsymmetricKeyPair* kp;
+ RSAParameters p;
+
+ // Public exponents to test
+ std::vector<ByteString> exponents;
+ exponents.push_back("010001");
+ exponents.push_back("03");
+ exponents.push_back("0B");
+ exponents.push_back("11");
+
+ // Key sizes to test
+ std::vector<size_t> keySizes;
+ keySizes.push_back(1024);
+ keySizes.push_back(1280);
+ keySizes.push_back(2048);
+ //keySizes.push_back(4096);
+
+ // Paddings to test
+ std::vector<AsymMech::Type> paddings;
+ paddings.push_back(AsymMech::RSA_PKCS);
+ paddings.push_back(AsymMech::RSA_PKCS_OAEP);
+ paddings.push_back(AsymMech::RSA);
+
+ for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
+ {
+ for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
+ {
+ p.setE(*e);
+ p.setBitLength(*k);
+
+ // Generate key-pair
+ CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
+
+ RNG* rng = CryptoFactory::i()->getRNG();
+
+ for (std::vector<AsymMech::Type>::iterator pad = paddings.begin(); pad != paddings.end(); pad++)
+ {
+ // Generate some test data to encrypt based on the selected padding
+ ByteString testData;
+
+ if (*pad == AsymMech::RSA_PKCS)
+ {
+ CPPUNIT_ASSERT(rng->generateRandom(testData, (*k >> 3) - 12));
+ }
+ else if (*pad == AsymMech::RSA_PKCS_OAEP)
+ {
+ CPPUNIT_ASSERT(rng->generateRandom(testData, (*k >> 3) - 42));
+ }
+ else if (*pad == AsymMech::RSA)
+ {
+ CPPUNIT_ASSERT(rng->generateRandom(testData, *k >> 3));
+ testData[0] &= 0x0F;
+ }
+ else
+ {
+ CPPUNIT_ASSERT(true == false);
+ }
+
+ // Encrypt the data
+ ByteString encryptedData;
+
+ CPPUNIT_ASSERT(rsa->encrypt(kp->getPublicKey(), testData, encryptedData, *pad));
+
+ // The encrypted data length should equal the modulus length
+ CPPUNIT_ASSERT(encryptedData.size() == (*k >> 3));
+ CPPUNIT_ASSERT(encryptedData != testData);
+
+ // Now decrypt the data
+ ByteString decryptedData;
+
+ CPPUNIT_ASSERT(rsa->decrypt(kp->getPrivateKey(), encryptedData, decryptedData, *pad));
+
+ // Check that the data was properly decrypted
+ CPPUNIT_ASSERT(decryptedData == testData);
+ }
+
+ rsa->recycleKeyPair(kp);
+ }
+ }
+}
+
diff --git a/SoftHSMv2/src/lib/crypto/test/RSATests.h b/SoftHSMv2/src/lib/crypto/test/RSATests.h
new file mode 100644
index 0000000..ca5c86d
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/RSATests.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ RSATests.h
+
+ Contains test cases to test the RSA class
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_RSATESTS_H
+#define _SOFTHSM_V2_RSATESTS_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include "AsymmetricAlgorithm.h"
+
+class RSATests : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(RSATests);
+ CPPUNIT_TEST(testKeyGeneration);
+ CPPUNIT_TEST(testSerialisation);
+ CPPUNIT_TEST(testPKCS8);
+ CPPUNIT_TEST(testSigningVerifying);
+ CPPUNIT_TEST(testSignVerifyKnownVector);
+ CPPUNIT_TEST(testEncryptDecrypt);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void testKeyGeneration();
+ void testSerialisation();
+ void testPKCS8();
+ void testSigningVerifying();
+ void testSignVerifyKnownVector();
+ void testEncryptDecrypt();
+
+ void setUp();
+ void tearDown();
+
+private:
+ // RSA instance
+ AsymmetricAlgorithm* rsa;
+};
+
+#endif // !_SOFTHSM_V2_RSATESTS_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/chisq.c b/SoftHSMv2/src/lib/crypto/test/chisq.c
new file mode 100644
index 0000000..3fe4f66
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/chisq.c
@@ -0,0 +1,144 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/*
+
+ Compute probability of measured Chi Square value.
+
+ This code was developed by Gary Perlman of the Wang
+ Institute (full citation below) and has been minimally
+ modified for use in this program.
+
+*/
+
+#include <math.h>
+
+/*HEADER
+ Module: z.c
+ Purpose: compute approximations to normal z distribution probabilities
+ Programmer: Gary Perlman
+ Organization: Wang Institute, Tyngsboro, MA 01879
+ Copyright: none
+ Tabstops: 4
+*/
+
+#define Z_MAX 6.0 /* maximum meaningful z value */
+
+/*FUNCTION poz: probability of normal z value */
+/*ALGORITHM
+ Adapted from a polynomial approximation in:
+ Ibbetson D, Algorithm 209
+ Collected Algorithms of the CACM 1963 p. 616
+ Note:
+ This routine has six digit accuracy, so it is only useful for absolute
+ z values < 6. For z values >= to 6.0, poz() returns 0.0.
+*/
+static double /*VAR returns cumulative probability from -oo to z */
+poz(const double z) /*VAR normal z value */
+{
+ double y, x, w;
+
+ if (z == 0.0) {
+ x = 0.0;
+ } else {
+ y = 0.5 * fabs(z);
+ if (y >= (Z_MAX * 0.5)) {
+ x = 1.0;
+ } else if (y < 1.0) {
+ w = y * y;
+ x = ((((((((0.000124818987 * w
+ -0.001075204047) * w +0.005198775019) * w
+ -0.019198292004) * w +0.059054035642) * w
+ -0.151968751364) * w +0.319152932694) * w
+ -0.531923007300) * w +0.797884560593) * y * 2.0;
+ } else {
+ y -= 2.0;
+ x = (((((((((((((-0.000045255659 * y
+ +0.000152529290) * y -0.000019538132) * y
+ -0.000676904986) * y +0.001390604284) * y
+ -0.000794620820) * y -0.002034254874) * y
+ +0.006549791214) * y -0.010557625006) * y
+ +0.011630447319) * y -0.009279453341) * y
+ +0.005353579108) * y -0.002141268741) * y
+ +0.000535310849) * y +0.999936657524;
+ }
+ }
+ return (z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5));
+}
+
+/*
+ Module: chisq.c
+ Purpose: compute approximations to chisquare distribution probabilities
+ Contents: pochisq()
+ Uses: poz() in z.c (Algorithm 209)
+ Programmer: Gary Perlman
+ Organization: Wang Institute, Tyngsboro, MA 01879
+ Copyright: none
+ Tabstops: 4
+*/
+
+#define LOG_SQRT_PI 0.5723649429247000870717135 /* log (sqrt (pi)) */
+#define I_SQRT_PI 0.5641895835477562869480795 /* 1 / sqrt (pi) */
+#define BIGX 20.0 /* max value to represent exp (x) */
+#define ex(x) (((x) < -BIGX) ? 0.0 : exp(x))
+
+/*FUNCTION pochisq: probability of chi sqaure value */
+/*ALGORITHM Compute probability of chi square value.
+ Adapted from:
+ Hill, I. D. and Pike, M. C. Algorithm 299
+ Collected Algorithms for the CACM 1967 p. 243
+ Updated for rounding errors based on remark in
+ ACM TOMS June 1985, page 185
+*/
+
+double pochisq(
+ const double ax, /* obtained chi-square value */
+ const int df /* degrees of freedom */
+ )
+{
+ double x = ax;
+ double a, y, s;
+ double e, c, z;
+ int even; /* true if df is an even number */
+
+ if (x <= 0.0 || df < 1) {
+ return 1.0;
+ }
+
+ a = 0.5 * x;
+ even = (2 * (df / 2)) == df;
+ y = 0.0;
+ if (df > 1) {
+ y = ex(-a);
+ }
+ s = (even ? y : (2.0 * poz(-sqrt(x))));
+ if (df > 2) {
+ x = 0.5 * (df - 1.0);
+ z = (even ? 1.0 : 0.5);
+ if (a > BIGX) {
+ e = (even ? 0.0 : LOG_SQRT_PI);
+ c = log(a);
+ while (z <= x) {
+ e = log(z) + e;
+ s += ex(c * z - a - e);
+ z += 1.0;
+ }
+ return (s);
+ } else {
+ e = (even ? 1.0 : (I_SQRT_PI / sqrt(a)));
+ c = 0.0;
+ while (z <= x) {
+ e = e * (a / z);
+ c = c + e;
+ z += 1.0;
+ }
+ return (c * y + s);
+ }
+ } else {
+ return s;
+ }
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/cryptotest.cpp b/SoftHSMv2/src/lib/crypto/test/cryptotest.cpp
new file mode 100644
index 0000000..2fc7b8f
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/cryptotest.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ cryptotest.cpp
+
+ The main test executor for tests on the cryptographic functions in SoftHSM v2
+ *****************************************************************************/
+
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/XmlOutputter.h>
+#include <fstream>
+
+#include "config.h"
+#include "MutexFactory.h"
+#include "SecureMemoryRegistry.h"
+
+#if defined(WITH_OPENSSL)
+#include "OSSLCryptoFactory.h"
+#else
+#include "BotanCryptoFactory.h"
+#endif
+
+// Initialise the one-and-only instance
+#ifdef HAVE_CXX11
+
+std::unique_ptr<MutexFactory> MutexFactory::instance(nullptr);
+std::unique_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(nullptr);
+#if defined(WITH_OPENSSL)
+std::unique_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(nullptr);
+#else
+std::unique_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(nullptr);
+#endif
+
+#else
+
+std::auto_ptr<MutexFactory> MutexFactory::instance(NULL);
+std::auto_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(NULL);
+#if defined(WITH_OPENSSL)
+std::auto_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(NULL);
+#else
+std::auto_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(NULL);
+#endif
+
+#endif
+
+int main(int /*argc*/, char** /*argv*/)
+{
+ CppUnit::TestResult controller;
+ CppUnit::TestResultCollector result;
+ CppUnit::TextUi::TestRunner runner;
+ controller.addListener(&result);
+ CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
+
+ runner.addTest(registry.makeTest());
+ runner.run(controller);
+
+ std::ofstream xmlFileOut("test-results.xml");
+ CppUnit::XmlOutputter xmlOut(&result, xmlFileOut);
+ xmlOut.write();
+
+ CryptoFactory::reset();
+
+ return result.wasSuccessful() ? 0 : 1;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/ent.c b/SoftHSMv2/src/lib/crypto/test/ent.c
new file mode 100644
index 0000000..b255405
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ent.c
@@ -0,0 +1,110 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/*
+ ENT -- Entropy calculation and analysis of putative
+ random sequences.
+
+ Designed and implemented by John "Random" Walker in May 1985.
+
+ Multiple analyses of random sequences added in December 1985.
+
+ Bit stream analysis added in September 1997.
+
+ Terse mode output, getopt() command line processing,
+ optional stdin input, and HTML documentation added in
+ October 1998.
+
+ Documentation for the -t (terse output) option added
+ in July 2006.
+
+ Replaced table look-up for chi square to probability
+ conversion with algorithmic computation in January 2008.
+
+ For additional information and the latest version,
+ see http://www.fourmilab.ch/random/
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#ifdef _WIN32
+#include <fcntl.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "iso8859.h"
+#include "randtest.h"
+
+#define UPDATE "January 28th, 2008"
+
+#define FALSE 0
+#define TRUE 1
+
+#ifdef M_PI
+#define PI M_PI
+#else
+#define PI 3.14159265358979323846
+#endif
+
+extern double pochisq(const double ax, const int df);
+
+/* Main program */
+
+void doEnt
+(
+ unsigned char* data,
+ size_t len,
+ double* pEntropy,
+ double* pChiProbability,
+ double* pArithMean,
+ double* pMontePi,
+ double* pSerialCorrelation
+)
+{
+ size_t s;
+ long ccount[256]; /* Bins to count occurrences of values */
+ double montepi, chip,
+ scc, ent, mean, chisq;
+
+ /* Initialise for calculations */
+
+ rt_init(FALSE);
+
+ /* Scan input file and count character occurrences */
+
+ for (s = 0; s < len; s++)
+ {
+ unsigned char ocb = data[s];
+
+ ccount[ocb]++; /* Update counter for this bin */
+ rt_add(&ocb, 1);
+ }
+
+ /* Complete calculation and return sequence metrics */
+
+ rt_end(&ent, &chisq, &mean, &montepi, &scc);
+
+ /* Calculate probability of observed distribution occurring from
+ the results of the Chi-Square test */
+
+ chip = pochisq(chisq, 255);
+
+ /* Print bin counts if requested */
+
+ /* Return calculated results */
+
+ *pEntropy = ent;
+ *pChiProbability = chip;
+ *pArithMean = mean;
+ *pMontePi = montepi;
+ *pSerialCorrelation = scc;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/ent.h b/SoftHSMv2/src/lib/crypto/test/ent.h
new file mode 100644
index 0000000..5958888
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/ent.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010 SURFnet bv
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ ent.h
+
+ Header file to give access to the modified ent.c implementation
+ *****************************************************************************/
+
+#ifndef _SOFTHSM_V2_ENT_H
+#define _SOFTHSM_V2_ENT_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void doEnt
+(
+ unsigned char* data,
+ size_t len,
+ double* pEntropy,
+ double* pChiProbability,
+ double* pArithMean,
+ double* pMontePi,
+ double* pSerialCorrelation
+);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // !_SOFTHSM_V2_ENT_H
+
diff --git a/SoftHSMv2/src/lib/crypto/test/iso8859.c b/SoftHSMv2/src/lib/crypto/test/iso8859.c
new file mode 100644
index 0000000..bed7244
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/iso8859.c
@@ -0,0 +1,25 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/* ISO 8859/1 Latin-1 alphabetic and upper and lower case bit vector tables. */
+
+/* LINTLIBRARY */
+
+unsigned char isoalpha[32] = {
+ 0,0,0,0,0,0,0,0,127,255,255,224,127,255,255,224,0,0,0,0,0,0,0,0,255,255,
+ 254,255,255,255,254,255
+};
+
+unsigned char isoupper[32] = {
+ 0,0,0,0,0,0,0,0,127,255,255,224,0,0,0,0,0,0,0,0,0,0,0,0,255,255,254,254,
+ 0,0,0,0
+};
+
+unsigned char isolower[32] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,127,255,255,224,0,0,0,0,0,0,0,0,0,0,0,1,255,255,
+ 254,255
+};
diff --git a/SoftHSMv2/src/lib/crypto/test/iso8859.h b/SoftHSMv2/src/lib/crypto/test/iso8859.h
new file mode 100644
index 0000000..7462f15
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/iso8859.h
@@ -0,0 +1,23 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/* ISO 8859/1 Latin-1 "ctype" macro replacements. */
+
+extern unsigned char isoalpha[32], isoupper[32], isolower[32];
+
+#define isISOspace(x) ((isascii(((unsigned char) (x))) && isspace(((unsigned char) (x)))) || ((x) == 0xA0))
+#define isISOalpha(x) ((isoalpha[(((unsigned char) (x))) / 8] & (0x80 >> ((((unsigned char) (x))) % 8))) != 0)
+#define isISOupper(x) ((isoupper[(((unsigned char) (x))) / 8] & (0x80 >> ((((unsigned char) (x))) % 8))) != 0)
+#define isISOlower(x) ((isolower[(((unsigned char) (x))) / 8] & (0x80 >> ((((unsigned char) (x))) % 8))) != 0)
+#define isISOprint(x) ((((x) >= ' ') && ((x) <= '~')) || ((x) >= 0xA0))
+#define toISOupper(x) (isISOlower(x) ? (isascii(((unsigned char) (x))) ? \
+ toupper(x) : (((((unsigned char) (x)) != 0xDF) && \
+ (((unsigned char) (x)) != 0xFF)) ? \
+ (((unsigned char) (x)) - 0x20) : (x))) : (x))
+#define toISOlower(x) (isISOupper(x) ? (isascii(((unsigned char) (x))) ? \
+ tolower(x) : (((unsigned char) (x)) + 0x20)) \
+ : (x))
diff --git a/SoftHSMv2/src/lib/crypto/test/randtest.c b/SoftHSMv2/src/lib/crypto/test/randtest.c
new file mode 100644
index 0000000..5a54737
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/randtest.c
@@ -0,0 +1,190 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/*
+
+ Apply various randomness tests to a stream of bytes
+
+ by John Walker -- September 1996
+ http://www.fourmilab.ch/
+
+*/
+
+#include <math.h>
+
+#define FALSE 0
+#define TRUE 1
+
+#define log2of10 3.32192809488736234787
+
+static int binary = FALSE; /* Treat input as a bitstream */
+
+static long ccount[256], /* Bins to count occurrences of values */
+ totalc = 0; /* Total bytes counted */
+static double prob[256]; /* Probabilities per bin for entropy */
+
+/* RT_LOG2 -- Calculate log to the base 2 */
+
+static double rt_log2(double x)
+{
+ return log2of10 * log10(x);
+}
+
+#define MONTEN 6 /* Bytes used as Monte Carlo
+ co-ordinates. This should be no more
+ bits than the mantissa of your
+ "double" floating point type. */
+
+static int mp, sccfirst;
+static unsigned int monte[MONTEN];
+static long inmont, mcount;
+static double cexp, incirc, montex, montey, montepi,
+ scc, sccun, sccu0, scclast, scct1, scct2, scct3,
+ ent, chisq, datasum;
+
+/* RT_INIT -- Initialise random test counters. */
+
+void rt_init(int binmode)
+{
+ int i;
+
+ binary = binmode; /* Set binary / byte mode */
+
+ /* Initialise for calculations */
+
+ ent = 0.0; /* Clear entropy accumulator */
+ chisq = 0.0; /* Clear Chi-Square */
+ datasum = 0.0; /* Clear sum of bytes for arithmetic mean */
+
+ mp = 0; /* Reset Monte Carlo accumulator pointer */
+ mcount = 0; /* Clear Monte Carlo tries */
+ inmont = 0; /* Clear Monte Carlo inside count */
+ incirc = 65535.0 * 65535.0;/* In-circle distance for Monte Carlo */
+
+ sccfirst = TRUE; /* Mark first time for serial correlation */
+ scct1 = scct2 = scct3 = 0.0; /* Clear serial correlation terms */
+
+ incirc = pow(pow(256.0, (double) (MONTEN / 2)) - 1, 2.0);
+
+ for (i = 0; i < 256; i++) {
+ ccount[i] = 0;
+ }
+ totalc = 0;
+}
+
+/* RT_ADD -- Add one or more bytes to accumulation. */
+
+void rt_add(void *buf, int bufl)
+{
+ unsigned char *bp = (unsigned char *)buf;
+ int oc, c, bean;
+
+ while (bean = 0, (bufl-- > 0)) {
+ oc = *bp++;
+
+ do {
+ if (binary) {
+ c = !!(oc & 0x80);
+ } else {
+ c = oc;
+ }
+ ccount[c]++; /* Update counter for this bin */
+ totalc++;
+
+ /* Update inside / outside circle counts for Monte Carlo
+ computation of PI */
+
+ if (bean == 0) {
+ monte[mp++] = oc; /* Save character for Monte Carlo */
+ if (mp >= MONTEN) { /* Calculate every MONTEN character */
+ int mj;
+
+ mp = 0;
+ mcount++;
+ montex = montey = 0;
+ for (mj = 0; mj < MONTEN / 2; mj++) {
+ montex = (montex * 256.0) + monte[mj];
+ montey = (montey * 256.0) + monte[(MONTEN / 2) + mj];
+ }
+ if ((montex * montex + montey * montey) <= incirc) {
+ inmont++;
+ }
+ }
+ }
+
+ /* Update calculation of serial correlation coefficient */
+
+ sccun = c;
+ if (sccfirst) {
+ sccfirst = FALSE;
+ scclast = 0;
+ sccu0 = sccun;
+ } else {
+ scct1 = scct1 + scclast * sccun;
+ }
+ scct2 = scct2 + sccun;
+ scct3 = scct3 + (sccun * sccun);
+ scclast = sccun;
+ oc <<= 1;
+ } while (binary && (++bean < 8));
+ }
+}
+
+/* RT_END -- Complete calculation and return results. */
+
+void rt_end(double *r_ent, double *r_chisq, double *r_mean,
+ double *r_montepicalc, double *r_scc)
+{
+ int i;
+
+ /* Complete calculation of serial correlation coefficient */
+
+ scct1 = scct1 + scclast * sccu0;
+ scct2 = scct2 * scct2;
+ scc = totalc * scct3 - scct2;
+ if (scc == 0.0) {
+ scc = -100000;
+ } else {
+ scc = (totalc * scct1 - scct2) / scc;
+ }
+
+ /* Scan bins and calculate probability for each bin and
+ Chi-Square distribution. The probability will be reused
+ in the entropy calculation below. While we're at it,
+ we sum of all the data which will be used to compute the
+ mean. */
+
+ cexp = totalc / (binary ? 2.0 : 256.0); /* Expected count per bin */
+ for (i = 0; i < (binary ? 2 : 256); i++) {
+ double a = ccount[i] - cexp;;
+
+ prob[i] = ((double) ccount[i]) / totalc;
+ chisq += (a * a) / cexp;
+ datasum += ((double) i) * ccount[i];
+ }
+
+ /* Calculate entropy */
+
+ for (i = 0; i < (binary ? 2 : 256); i++) {
+ if (prob[i] > 0.0) {
+ ent += prob[i] * rt_log2(1 / prob[i]);
+ }
+ }
+
+ /* Calculate Monte Carlo value for PI from percentage of hits
+ within the circle */
+
+ montepi = 4.0 * (((double) inmont) / mcount);
+
+ /* Return results through arguments */
+
+ *r_ent = ent;
+ *r_chisq = chisq;
+ *r_mean = datasum / totalc;
+ *r_montepicalc = montepi;
+ *r_scc = scc;
+}
diff --git a/SoftHSMv2/src/lib/crypto/test/randtest.h b/SoftHSMv2/src/lib/crypto/test/randtest.h
new file mode 100644
index 0000000..53bef35
--- /dev/null
+++ b/SoftHSMv2/src/lib/crypto/test/randtest.h
@@ -0,0 +1,13 @@
+/* This code was taken from http://www.fourmilab.ch/random/ where it states that:
+
+ This software is in the public domain. Permission to use, copy, modify, and distribute
+ this software and its documentation for any purpose and without fee is hereby granted,
+ without any conditions or restrictions. This software is provided “as is” without
+ express or implied warranty. */
+
+/* Random test function prototypes */
+
+extern void rt_init(int binmode);
+extern void rt_add(void *buf, int bufl);
+extern void rt_end(double *r_ent, double *r_chisq, double *r_mean,
+ double *r_montepicalc, double *r_scc);