@@ -232,6 +232,26 @@ CK_RV ck_sign(
232
232
) {
233
233
return (*fl->C_Sign)(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
234
234
}
235
+
236
+ CK_RV ck_decrypt_init(
237
+ CK_FUNCTION_LIST_PTR fl,
238
+ CK_SESSION_HANDLE hSession,
239
+ CK_MECHANISM_PTR pMechanism,
240
+ CK_OBJECT_HANDLE hKey
241
+ ) {
242
+ return (*fl->C_DecryptInit)(hSession, pMechanism, hKey);
243
+ }
244
+
245
+ CK_RV ck_decrypt(
246
+ CK_FUNCTION_LIST_PTR fl,
247
+ CK_SESSION_HANDLE hSession,
248
+ CK_BYTE_PTR pEncryptedData,
249
+ CK_ULONG ulEncryptedDataLen,
250
+ CK_BYTE_PTR pData,
251
+ CK_ULONG_PTR pulDataLen
252
+ ) {
253
+ return (*fl->C_Decrypt)(hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen);
254
+ }
235
255
*/
236
256
// #cgo linux LDFLAGS: -ldl
237
257
import "C"
@@ -1226,20 +1246,15 @@ func (r *rsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts)
1226
1246
// http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/cs01/pkcs11-curr-v2.40-cs01.html#_Toc399398842
1227
1247
size := opts .HashFunc ().Size ()
1228
1248
if size != len (digest ) {
1229
- return nil , fmt .Errorf ("input mush be hashed" )
1249
+ return nil , fmt .Errorf ("input must be hashed" )
1230
1250
}
1231
1251
prefix , ok := hashPrefixes [opts .HashFunc ()]
1232
1252
if ! ok {
1233
1253
return nil , fmt .Errorf ("unsupported hash function: %s" , opts .HashFunc ())
1234
1254
}
1235
1255
1236
- cBytes := make ([]C.CK_BYTE , len (prefix )+ len (digest ))
1237
- for i , b := range prefix {
1238
- cBytes [i ] = C .CK_BYTE (b )
1239
- }
1240
- for i , b := range digest {
1241
- cBytes [len (prefix )+ i ] = C .CK_BYTE (b )
1242
- }
1256
+ preAndDigest := append (prefix , digest ... )
1257
+ cBytes := toCBytes (preAndDigest )
1243
1258
1244
1259
cSig := make ([]C.CK_BYTE , r .pub .Size ())
1245
1260
cSigLen := C .CK_ULONG (len (cSig ))
@@ -1257,10 +1272,7 @@ func (r *rsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts)
1257
1272
if int (cSigLen ) != len (cSig ) {
1258
1273
return nil , fmt .Errorf ("expected signature of length %d, got %d" , len (cSig ), cSigLen )
1259
1274
}
1260
- sig := make ([]byte , len (cSig ))
1261
- for i , b := range cSig {
1262
- sig [i ] = byte (b )
1263
- }
1275
+ sig := toBytes (cSig )
1264
1276
return sig , nil
1265
1277
}
1266
1278
@@ -1295,10 +1307,7 @@ func (r *rsaPrivateKey) signPSS(digest []byte, opts *rsa.PSSOptions) ([]byte, er
1295
1307
cParam .sLen = C .CK_ULONG (opts .SaltLength )
1296
1308
}
1297
1309
1298
- cBytes := make ([]C.CK_BYTE , len (digest ))
1299
- for i , b := range digest {
1300
- cBytes [i ] = C .CK_BYTE (b )
1301
- }
1310
+ cBytes := toCBytes (digest )
1302
1311
1303
1312
cSig := make ([]C.CK_BYTE , r .pub .Size ())
1304
1313
cSigLen := C .CK_ULONG (len (cSig ))
@@ -1321,10 +1330,7 @@ func (r *rsaPrivateKey) signPSS(digest []byte, opts *rsa.PSSOptions) ([]byte, er
1321
1330
if int (cSigLen ) != len (cSig ) {
1322
1331
return nil , fmt .Errorf ("expected signature of length %d, got %d" , len (cSig ), cSigLen )
1323
1332
}
1324
- sig := make ([]byte , len (cSig ))
1325
- for i , b := range cSig {
1326
- sig [i ] = byte (b )
1327
- }
1333
+ sig := toBytes (cSig )
1328
1334
return sig , nil
1329
1335
}
1330
1336
@@ -1353,10 +1359,7 @@ func (e *ecdsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpt
1353
1359
cSig := make ([]C.CK_BYTE , byteLen * 2 )
1354
1360
cSigLen := C .CK_ULONG (len (cSig ))
1355
1361
1356
- cBytes := make ([]C.CK_BYTE , len (digest ))
1357
- for i , b := range digest {
1358
- cBytes [i ] = C .CK_BYTE (b )
1359
- }
1362
+ cBytes := toCBytes (digest )
1360
1363
1361
1364
rv = C .ck_sign (e .o .fl , e .o .h , & cBytes [0 ], C .CK_ULONG (len (digest )), & cSig [0 ], & cSigLen )
1362
1365
if err := isOk ("C_Sign" , rv ); err != nil {
@@ -1366,10 +1369,7 @@ func (e *ecdsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpt
1366
1369
if int (cSigLen ) != len (cSig ) {
1367
1370
return nil , fmt .Errorf ("expected signature of length %d, got %d" , len (cSig ), cSigLen )
1368
1371
}
1369
- sig := make ([]byte , len (cSig ))
1370
- for i , b := range cSig {
1371
- sig [i ] = byte (b )
1372
- }
1372
+ sig := toBytes (cSig )
1373
1373
1374
1374
var (
1375
1375
r = big .NewInt (0 )
@@ -1687,3 +1687,86 @@ func (s *Slot) generateECDSA(o keyOptions) (crypto.PrivateKey, error) {
1687
1687
}
1688
1688
return priv , nil
1689
1689
}
1690
+
1691
+ func (r * rsaPrivateKey ) Decrypt (_ io.Reader , encryptedData []byte , opts crypto.DecrypterOpts ) ([]byte , error ) {
1692
+ var m C.CK_MECHANISM
1693
+
1694
+ if o , ok := opts .(* rsa.OAEPOptions ); ok {
1695
+ cParam := (C .CK_RSA_PKCS_OAEP_PARAMS_PTR )(C .malloc (C .sizeof_CK_RSA_PKCS_OAEP_PARAMS ))
1696
+ defer C .free (unsafe .Pointer (cParam ))
1697
+
1698
+ switch o .Hash {
1699
+ case crypto .SHA256 :
1700
+ cParam .hashAlg = C .CKM_SHA256
1701
+ cParam .mgf = C .CKG_MGF1_SHA256
1702
+ case crypto .SHA384 :
1703
+ cParam .hashAlg = C .CKM_SHA384
1704
+ cParam .mgf = C .CKG_MGF1_SHA384
1705
+ case crypto .SHA512 :
1706
+ cParam .hashAlg = C .CKM_SHA512
1707
+ cParam .mgf = C .CKG_MGF1_SHA512
1708
+ case crypto .SHA1 :
1709
+ cParam .hashAlg = C .CKM_SHA_1
1710
+ cParam .mgf = C .CKG_MGF1_SHA1
1711
+ default :
1712
+ return nil , fmt .Errorf ("decryptOAEP error, unsupported hash algorithm: %s" , o .Hash )
1713
+ }
1714
+
1715
+ cParam .source = C .CKZ_DATA_SPECIFIED
1716
+ cParam .pSourceData = nil
1717
+ cParam .ulSourceDataLen = 0
1718
+
1719
+ m = C.CK_MECHANISM {
1720
+ mechanism : C .CKM_RSA_PKCS_OAEP ,
1721
+ pParameter : C .CK_VOID_PTR (cParam ),
1722
+ ulParameterLen : C .CK_ULONG (C .sizeof_CK_RSA_PKCS_OAEP_PARAMS ),
1723
+ }
1724
+ } else {
1725
+ m = C.CK_MECHANISM {C .CKM_RSA_PKCS , nil , 0 }
1726
+ }
1727
+
1728
+ cEncDataBytes := toCBytes (encryptedData )
1729
+
1730
+ rv := C .ck_decrypt_init (r .o .fl , r .o .h , & m , r .o .o )
1731
+ if err := isOk ("C_DecryptInit" , rv ); err != nil {
1732
+ return nil , err
1733
+ }
1734
+
1735
+ var cDecryptedLen C.CK_ULONG
1736
+
1737
+ // First call is used to determine length necessary to hold decrypted data (PKCS #11 5.2)
1738
+ rv = C .ck_decrypt (r .o .fl , r .o .h , & cEncDataBytes [0 ], C .CK_ULONG (len (cEncDataBytes )), nil , & cDecryptedLen )
1739
+ if err := isOk ("C_Decrypt" , rv ); err != nil {
1740
+ return nil , err
1741
+ }
1742
+
1743
+ cDecrypted := make ([]C.CK_BYTE , cDecryptedLen )
1744
+
1745
+ rv = C .ck_decrypt (r .o .fl , r .o .h , & cEncDataBytes [0 ], C .CK_ULONG (len (cEncDataBytes )), & cDecrypted [0 ], & cDecryptedLen )
1746
+ if err := isOk ("C_Decrypt" , rv ); err != nil {
1747
+ return nil , err
1748
+ }
1749
+
1750
+ decrypted := toBytes (cDecrypted )
1751
+
1752
+ // Removes null padding (PKCS#11 5.2): http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html#_Toc416959738
1753
+ decrypted = bytes .Trim (decrypted , "\x00 " )
1754
+
1755
+ return decrypted , nil
1756
+ }
1757
+
1758
+ func toBytes (data []C.CK_BYTE ) []byte {
1759
+ goBytes := make ([]byte , len (data ))
1760
+ for i , b := range data {
1761
+ goBytes [i ] = byte (b )
1762
+ }
1763
+ return goBytes
1764
+ }
1765
+
1766
+ func toCBytes (data []byte ) []C.CK_BYTE {
1767
+ cBytes := make ([]C.CK_BYTE , len (data ))
1768
+ for i , b := range data {
1769
+ cBytes [i ] = C .CK_BYTE (b )
1770
+ }
1771
+ return cBytes
1772
+ }
0 commit comments