@@ -232,6 +232,26 @@ CK_RV ck_sign(
232232) {
233233 return (*fl->C_Sign)(hSession, pData, ulDataLen, pSignature, pulSignatureLen);
234234}
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+ }
235255*/
236256// #cgo linux LDFLAGS: -ldl
237257import "C"
@@ -1226,20 +1246,15 @@ func (r *rsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts)
12261246 // http://docs.oasis-open.org/pkcs11/pkcs11-curr/v2.40/cs01/pkcs11-curr-v2.40-cs01.html#_Toc399398842
12271247 size := opts .HashFunc ().Size ()
12281248 if size != len (digest ) {
1229- return nil , fmt .Errorf ("input mush be hashed" )
1249+ return nil , fmt .Errorf ("input must be hashed" )
12301250 }
12311251 prefix , ok := hashPrefixes [opts .HashFunc ()]
12321252 if ! ok {
12331253 return nil , fmt .Errorf ("unsupported hash function: %s" , opts .HashFunc ())
12341254 }
12351255
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 )
12431258
12441259 cSig := make ([]C.CK_BYTE , r .pub .Size ())
12451260 cSigLen := C .CK_ULONG (len (cSig ))
@@ -1257,10 +1272,7 @@ func (r *rsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpts)
12571272 if int (cSigLen ) != len (cSig ) {
12581273 return nil , fmt .Errorf ("expected signature of length %d, got %d" , len (cSig ), cSigLen )
12591274 }
1260- sig := make ([]byte , len (cSig ))
1261- for i , b := range cSig {
1262- sig [i ] = byte (b )
1263- }
1275+ sig := toBytes (cSig )
12641276 return sig , nil
12651277}
12661278
@@ -1295,10 +1307,7 @@ func (r *rsaPrivateKey) signPSS(digest []byte, opts *rsa.PSSOptions) ([]byte, er
12951307 cParam .sLen = C .CK_ULONG (opts .SaltLength )
12961308 }
12971309
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 )
13021311
13031312 cSig := make ([]C.CK_BYTE , r .pub .Size ())
13041313 cSigLen := C .CK_ULONG (len (cSig ))
@@ -1321,10 +1330,7 @@ func (r *rsaPrivateKey) signPSS(digest []byte, opts *rsa.PSSOptions) ([]byte, er
13211330 if int (cSigLen ) != len (cSig ) {
13221331 return nil , fmt .Errorf ("expected signature of length %d, got %d" , len (cSig ), cSigLen )
13231332 }
1324- sig := make ([]byte , len (cSig ))
1325- for i , b := range cSig {
1326- sig [i ] = byte (b )
1327- }
1333+ sig := toBytes (cSig )
13281334 return sig , nil
13291335}
13301336
@@ -1353,10 +1359,7 @@ func (e *ecdsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpt
13531359 cSig := make ([]C.CK_BYTE , byteLen * 2 )
13541360 cSigLen := C .CK_ULONG (len (cSig ))
13551361
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 )
13601363
13611364 rv = C .ck_sign (e .o .fl , e .o .h , & cBytes [0 ], C .CK_ULONG (len (digest )), & cSig [0 ], & cSigLen )
13621365 if err := isOk ("C_Sign" , rv ); err != nil {
@@ -1366,10 +1369,7 @@ func (e *ecdsaPrivateKey) Sign(_ io.Reader, digest []byte, opts crypto.SignerOpt
13661369 if int (cSigLen ) != len (cSig ) {
13671370 return nil , fmt .Errorf ("expected signature of length %d, got %d" , len (cSig ), cSigLen )
13681371 }
1369- sig := make ([]byte , len (cSig ))
1370- for i , b := range cSig {
1371- sig [i ] = byte (b )
1372- }
1372+ sig := toBytes (cSig )
13731373
13741374 var (
13751375 r = big .NewInt (0 )
@@ -1687,3 +1687,86 @@ func (s *Slot) generateECDSA(o keyOptions) (crypto.PrivateKey, error) {
16871687 }
16881688 return priv , nil
16891689}
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