@@ -90,7 +90,7 @@ public class BIP32Keystore: AbstractKeystore {
90
90
try createNewAccount ( parentNode: rootNode, password: password)
91
91
}
92
92
93
- public func createNewAccount( parentNode: HDNode , password: String = " BANKEXFOUNDATION " ) throws {
93
+ public func createNewAccount( parentNode: HDNode , password: String = " BANKEXFOUNDATION " , aesMode : String = " aes-128-cbc " ) throws {
94
94
var newIndex = UInt32 ( 0 )
95
95
for (p, _) in paths {
96
96
guard let idx = UInt32 ( p. components ( separatedBy: " / " ) . last!) else { continue }
@@ -109,7 +109,7 @@ public class BIP32Keystore: AbstractKeystore {
109
109
}
110
110
paths [ newPath] = newAddress
111
111
guard let serializedRootNode = parentNode. serialize ( serializePublic: false ) else { throw AbstractKeystoreError . keyDerivationError}
112
- try encryptDataToStorage ( password, data: serializedRootNode)
112
+ try encryptDataToStorage ( password, data: serializedRootNode, aesMode : aesMode )
113
113
}
114
114
115
115
public func createNewCustomChildAccount( password: String = " BANKEXFOUNDATION " , path: String ) throws {
@@ -146,10 +146,10 @@ public class BIP32Keystore: AbstractKeystore {
146
146
}
147
147
paths [ newPath] = newAddress
148
148
guard let serializedRootNode = rootNode. serialize ( serializePublic: false ) else { throw AbstractKeystoreError . keyDerivationError}
149
- try encryptDataToStorage ( password, data: serializedRootNode)
149
+ try encryptDataToStorage ( password, data: serializedRootNode, aesMode : self . keystoreParams! . crypto . cipher )
150
150
}
151
151
152
- fileprivate func encryptDataToStorage( _ password: String , data: Data ? , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 ) throws {
152
+ fileprivate func encryptDataToStorage( _ password: String , data: Data ? , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 , aesMode : String = " aes-128-cbc " ) throws {
153
153
if ( data == nil ) {
154
154
throw AbstractKeystoreError . encryptionError ( " Encryption without key data " )
155
155
}
@@ -162,16 +162,27 @@ public class BIP32Keystore: AbstractKeystore {
162
162
let last16bytes = derivedKey [ ( derivedKey. count - 16 ) ... ( derivedKey. count- 1 ) ]
163
163
let encryptionKey = derivedKey [ 0 ... 15 ]
164
164
guard let IV = Data . randomBytes ( length: 16 ) else { throw AbstractKeystoreError . noEntropyError}
165
- let aecCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . pkcs7)
166
- guard let encryptedKey = try aecCipher? . encrypt ( data!. bytes) else { throw AbstractKeystoreError . aesError}
165
+ var aesCipher : AES ?
166
+ switch aesMode {
167
+ case " aes-128-cbc " :
168
+ aesCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . pkcs7)
169
+ case " aes-128-ctr " :
170
+ aesCipher = try ? AES ( key: encryptionKey. bytes, blockMode: CTR ( iv: IV . bytes) , padding: . pkcs7)
171
+ default :
172
+ aesCipher = nil
173
+ }
174
+ if aesCipher == nil {
175
+ throw AbstractKeystoreError . aesError
176
+ }
177
+ guard let encryptedKey = try aesCipher? . encrypt ( data!. bytes) else { throw AbstractKeystoreError . aesError}
167
178
let encryptedKeyData = Data ( bytes: encryptedKey)
168
179
var dataForMAC = Data ( )
169
180
dataForMAC. append ( last16bytes)
170
181
dataForMAC. append ( encryptedKeyData)
171
182
let mac = dataForMAC. sha3 ( . keccak256)
172
183
let kdfparams = KdfParamsV3 ( salt: saltData. toHexString ( ) , dklen: dkLen, n: N, p: P, r: R, c: nil , prf: nil )
173
184
let cipherparams = CipherParamsV3 ( iv: IV . toHexString ( ) )
174
- let crypto = CryptoParamsV3 ( ciphertext: encryptedKeyData. toHexString ( ) , cipher: " aes-128-cbc " , cipherparams: cipherparams, kdf: " scrypt " , kdfparams: kdfparams, mac: mac. toHexString ( ) , version: nil )
185
+ let crypto = CryptoParamsV3 ( ciphertext: encryptedKeyData. toHexString ( ) , cipher: aesMode , cipherparams: cipherparams, kdf: " scrypt " , kdfparams: kdfparams, mac: mac. toHexString ( ) , version: nil )
175
186
var pathToAddress = [ String: String] ( )
176
187
for (path, address) in paths {
177
188
pathToAddress [ path] = address. address
@@ -188,7 +199,7 @@ public class BIP32Keystore: AbstractKeystore {
188
199
throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " )
189
200
}
190
201
defer { Data . zero ( & keyData!) }
191
- try self . encryptDataToStorage ( newPassword, data: keyData!)
202
+ try self . encryptDataToStorage ( newPassword, data: keyData!, aesMode : self . keystoreParams! . crypto . cipher )
192
203
}
193
204
194
205
fileprivate func getPrefixNodeData( _ password: String ) throws -> Data ? {
@@ -206,14 +217,14 @@ public class BIP32Keystore: AbstractKeystore {
206
217
guard let algo = keystorePars. crypto. kdfparams. prf else { return nil }
207
218
var hashVariant : HMAC . Variant ? ;
208
219
switch algo {
209
- case " hmac-sha256 " :
210
- hashVariant = HMAC . Variant. sha256
211
- case " hmac-sha384 " :
212
- hashVariant = HMAC . Variant. sha384
213
- case " hmac-sha512 " :
214
- hashVariant = HMAC . Variant. sha512
215
- default :
216
- hashVariant = nil
220
+ case " hmac-sha256 " :
221
+ hashVariant = HMAC . Variant. sha256
222
+ case " hmac-sha384 " :
223
+ hashVariant = HMAC . Variant. sha384
224
+ case " hmac-sha512 " :
225
+ hashVariant = HMAC . Variant. sha512
226
+ default :
227
+ hashVariant = nil
217
228
}
218
229
guard ( hashVariant != nil ) else { return nil }
219
230
guard let c = keystorePars. crypto. kdfparams. c else { return nil }
@@ -237,14 +248,14 @@ public class BIP32Keystore: AbstractKeystore {
237
248
guard let IV = Data . fromHex ( keystorePars. crypto. cipherparams. iv) else { return nil }
238
249
var decryptedPK : Array < UInt8 > ?
239
250
switch cipher {
240
- case " aes-128-ctr " :
241
- guard let aesCipher = try ? AES ( key: decryptionKey. bytes, blockMode: CTR ( iv: IV . bytes) , padding: . pkcs7) else { return nil }
242
- decryptedPK = try aesCipher. decrypt ( cipherText. bytes)
243
- case " aes-128-cbc " :
244
- guard let aesCipher = try ? AES ( key: decryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . pkcs7) else { return nil }
245
- decryptedPK = try ? aesCipher. decrypt ( cipherText. bytes)
246
- default :
247
- return nil
251
+ case " aes-128-ctr " :
252
+ guard let aesCipher = try ? AES ( key: decryptionKey. bytes, blockMode: CTR ( iv: IV . bytes) , padding: . pkcs7) else { return nil }
253
+ decryptedPK = try aesCipher. decrypt ( cipherText. bytes)
254
+ case " aes-128-cbc " :
255
+ guard let aesCipher = try ? AES ( key: decryptionKey. bytes, blockMode: CBC ( iv: IV . bytes) , padding: . pkcs7) else { return nil }
256
+ decryptedPK = try ? aesCipher. decrypt ( cipherText. bytes)
257
+ default :
258
+ return nil
248
259
}
249
260
guard decryptedPK != nil else { return nil }
250
261
guard decryptedPK? . count == 82 else { return nil }
0 commit comments