CipherBlockMode.swift 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //
  2. // CipherBlockMode.swift
  3. // CryptoSwift
  4. //
  5. // Created by Marcin Krzyzanowski on 27/12/14.
  6. // Copyright (c) 2014 Marcin Krzyzanowski. All rights reserved.
  7. //
  8. import Foundation
  9. public enum CipherBlockMode {
  10. case Plain, CBC, CFB
  11. /**
  12. Process input blocks with given block cipher mode. With fallback to plain mode.
  13. :param: blocks cipher block size blocks
  14. :param: iv IV
  15. :param: cipher single block encryption closure
  16. :returns: encrypted bytes
  17. */
  18. func encryptBlocks(blocks:[[Byte]], iv:[Byte]?, cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  19. // if IV is not available, fallback to plain
  20. var finalBlockMode:CipherBlockMode = self
  21. if (iv == nil) {
  22. finalBlockMode = .Plain
  23. }
  24. switch (finalBlockMode) {
  25. case CBC:
  26. return CBCMode.encryptBlocks(blocks, iv: iv, cipher: cipher)
  27. case CFB:
  28. return CFBMode.encryptBlocks(blocks, iv: iv, cipher: cipher)
  29. case Plain:
  30. return PlainMode.encryptBlocks(blocks, cipher: cipher)
  31. }
  32. }
  33. func decryptBlocks(blocks:[[Byte]], iv:[Byte]?, cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  34. // if IV is not available, fallback to plain
  35. var finalBlockMode:CipherBlockMode = self
  36. if (iv == nil) {
  37. finalBlockMode = .Plain
  38. }
  39. switch (finalBlockMode) {
  40. case CBC:
  41. return CBCMode.decryptBlocks(blocks, iv: iv, cipher: cipher)
  42. case CFB:
  43. return CFBMode.decryptBlocks(blocks, iv: iv, cipher: cipher)
  44. case Plain:
  45. return PlainMode.decryptBlocks(blocks, cipher: cipher)
  46. }
  47. }
  48. }
  49. /**
  50. * Cipher-block chaining (CBC)
  51. */
  52. private struct CBCMode {
  53. static func encryptBlocks(blocks:[[Byte]], iv:[Byte]?, cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  54. if (iv == nil) {
  55. assertionFailure("CBC require IV")
  56. return nil
  57. }
  58. var out:[Byte]?
  59. var lastCiphertext:[Byte] = iv!
  60. for (idx,plaintext) in enumerate(blocks) {
  61. // for the first time ciphertext = iv
  62. // ciphertext = plaintext (+) ciphertext
  63. var xoredPlaintext:[Byte] = plaintext
  64. for i in 0..<plaintext.count {
  65. xoredPlaintext[i] = lastCiphertext[i] ^ plaintext[i]
  66. }
  67. // encrypt with cipher
  68. if let encrypted = cipher(block: xoredPlaintext) {
  69. lastCiphertext = encrypted
  70. if (out == nil) {
  71. out = [Byte]()
  72. }
  73. out = out! + encrypted
  74. }
  75. }
  76. return out;
  77. }
  78. static func decryptBlocks(blocks:[[Byte]], iv:[Byte]?, cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  79. if (iv == nil) {
  80. assertionFailure("CBC require IV")
  81. return nil
  82. }
  83. var out:[Byte]?
  84. var lastCiphertext:[Byte] = iv!
  85. for (idx,ciphertext) in enumerate(blocks) {
  86. if let decrypted = cipher(block: ciphertext) { // decrypt
  87. var xored:[Byte] = [Byte](count: lastCiphertext.count, repeatedValue: 0)
  88. for i in 0..<ciphertext.count {
  89. xored[i] = lastCiphertext[i] ^ decrypted[i]
  90. }
  91. if (out == nil) {
  92. out = [Byte]()
  93. }
  94. out = out! + xored
  95. }
  96. lastCiphertext = ciphertext
  97. }
  98. return out
  99. }
  100. }
  101. /**
  102. * Cipher feedback (CFB)
  103. */
  104. private struct CFBMode {
  105. static func encryptBlocks(blocks:[[Byte]], iv:[Byte]?, cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  106. if (iv == nil) {
  107. assertionFailure("CFB require IV")
  108. return nil
  109. }
  110. var out:[Byte]?
  111. var lastCiphertext:[Byte] = iv!
  112. for (idx,plaintext) in enumerate(blocks) {
  113. if let encrypted = cipher(block: lastCiphertext) {
  114. var xoredPlaintext:[Byte] = [Byte](count: plaintext.count, repeatedValue: 0)
  115. for i in 0..<plaintext.count {
  116. xoredPlaintext[i] = plaintext[i] ^ encrypted[i]
  117. }
  118. lastCiphertext = xoredPlaintext
  119. if (out == nil) {
  120. out = [Byte]()
  121. }
  122. out = out! + xoredPlaintext
  123. }
  124. }
  125. return out;
  126. }
  127. static func decryptBlocks(blocks:[[Byte]], iv:[Byte]?, cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  128. if (iv == nil) {
  129. assertionFailure("CFB require IV")
  130. return nil
  131. }
  132. var out:[Byte]?
  133. var lastCiphertext:[Byte] = iv!
  134. for (idx,ciphertext) in enumerate(blocks) {
  135. if let decrypted = cipher(block: lastCiphertext) {
  136. var xored:[Byte] = [Byte](count: ciphertext.count, repeatedValue: 0)
  137. for i in 0..<ciphertext.count {
  138. xored[i] = ciphertext[i] ^ decrypted[i]
  139. }
  140. lastCiphertext = xored
  141. if (out == nil) {
  142. out = [Byte]()
  143. }
  144. out = out! + xored
  145. }
  146. }
  147. return out;
  148. }
  149. }
  150. /**
  151. * Plain mode, don't use it. For debuging purposes only
  152. */
  153. private struct PlainMode {
  154. static func encryptBlocks(blocks:[[Byte]], cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  155. var out:[Byte]?
  156. for (idx,plaintext) in enumerate(blocks) {
  157. if let encrypted = cipher(block: plaintext) {
  158. if (out == nil) {
  159. out = [Byte]()
  160. }
  161. out = out! + encrypted
  162. }
  163. }
  164. return out
  165. }
  166. static func decryptBlocks(blocks:[[Byte]], cipher:(block:[Byte]) -> [Byte]?) -> [Byte]? {
  167. return encryptBlocks(blocks, cipher: cipher)
  168. }
  169. }