         case noPadding = 0, pkcs7Padding
     }
     
-    open static func crypt(_ opMode: OpMode, blockMode: BlockMode,
-                           algorithm: Algorithm, padding: Padding,
-                           data: Data, key: Data, iv: Data) throws -> Data {
+    public static func crypt(_ opMode: OpMode, blockMode: BlockMode,
+                             algorithm: Algorithm, padding: Padding,
+                             data: Data, key: Data, iv: Data) throws -> Data {
         if blockMode.needIV {
             guard iv.count == algorithm.blockSize else { throw CCError(.paramError) }
         }
         
         var cryptor: CCCryptorRef? = nil
-        var status = CCCryptorCreateWithMode!(
-            opMode.rawValue, blockMode.rawValue,
-            algorithm.rawValue, padding.rawValue,
-            (iv as NSData).bytes, (key as NSData).bytes, key.count,
-            nil, 0, 0,
-            CCModeOptions(), &cryptor)
+        var status = withUnsafePointers(iv, key, { ivBytes, keyBytes in
+            return CCCryptorCreateWithMode!(
+                opMode.rawValue, blockMode.rawValue,
+                algorithm.rawValue, padding.rawValue,
+                ivBytes, keyBytes, key.count,
+                nil, 0, 0,
+                CCModeOptions(), &cryptor)
+        })
+        
         guard status == noErr else { throw CCError(status) }
         
         defer { _ = CCCryptorRelease!(cryptor!) }
         
         let needed = CCCryptorGetOutputLength!(cryptor!, data.count, true)
         var result = Data(count: needed)
+        let rescount = result.count
         var updateLen: size_t = 0
-        status = result.withUnsafeMutableBytes({ (resultBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
+        status = withUnsafePointers(data, &result, { dataBytes, resultBytes in
             return CCCryptorUpdate!(
                 cryptor!,
-                (data as NSData).bytes, data.count,
-                resultBytes, result.count,
+                dataBytes, data.count,
+                resultBytes, rescount,
                 &updateLen)
         })
         guard status == noErr else { throw CCError(status) }
         
         
         var finalLen: size_t = 0
-        status = result.withUnsafeMutableBytes({ (resultBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
+        status = result.withUnsafeMutableBytes { resultBytes in
             return CCCryptorFinal!(
                 cryptor!,
                 resultBytes + updateLen,
-                result.count - updateLen,
+                rescount - updateLen,
                 &finalLen)
-        })
+        }
         guard status == noErr else { throw CCError(status) }
         
         

        }
    }
    
    open static func generateRandom(_ size: Int) -> Data {
        var data = Data(count: size)
        data.withUnsafeMutableBytes { (dataBytes: UnsafeMutablePointer<UInt8>) -> Void in
            _ = CCRandomGenerateBytes!(dataBytes, size)
        }
        return data

            return data
        }
        
        public static func toPEM(_ derKey: Data) -> String {
            let base64 = PEM.base64Encode(derKey)
            return addHeader(base64)
        }
