PKCS7Padding.swift 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // PKCS7PAdding.swift
  3. // CryptoSwift
  4. //
  5. // Copyright (C) 2014-2017 Marcin Krzyżanowski <marcin@krzyzanowskim.com>
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. //
  8. // In no event will the authors be held liable for any damages arising from the use of this software.
  9. //
  10. // Permission is granted to anyone to use this software for any purpose,including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
  11. //
  12. // - The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation is required.
  13. // - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  14. // - This notice may not be removed or altered from any source or binary distribution.
  15. //
  16. // PKCS is a group of public-key cryptography standards devised
  17. // and published by RSA Security Inc, starting in the early 1990s.
  18. //
  19. public struct PKCS7Padding: Padding {
  20. public enum Error: Swift.Error {
  21. case invalidPaddingValue
  22. }
  23. public init() {
  24. }
  25. public func add(to bytes: Array<UInt8>, blockSize: Int) -> Array<UInt8> {
  26. let padding = UInt8(blockSize - (bytes.count % blockSize))
  27. var withPadding = bytes
  28. if padding == 0 {
  29. // If the original data is a multiple of N bytes, then an extra block of bytes with value N is added.
  30. for _ in 0..<blockSize {
  31. withPadding += Array<UInt8>(arrayLiteral:UInt8(blockSize))
  32. }
  33. } else {
  34. // The value of each added byte is the number of bytes that are added
  35. for _ in 0..<padding {
  36. withPadding += Array<UInt8>(arrayLiteral:UInt8(padding))
  37. }
  38. }
  39. return withPadding
  40. }
  41. public func remove(from bytes: Array<UInt8>, blockSize _: Int?) -> Array<UInt8> {
  42. guard !bytes.isEmpty, let lastByte = bytes.last else {
  43. return bytes
  44. }
  45. assert(!bytes.isEmpty, "Need bytes to remove padding")
  46. let padding = Int(lastByte) // last byte
  47. let finalLength = bytes.count - padding
  48. if finalLength < 0 {
  49. return bytes
  50. }
  51. if padding >= 1 {
  52. return Array(bytes[0..<finalLength])
  53. }
  54. return bytes
  55. }
  56. }