|
| 1 | +// |
| 2 | +// CryptoSwift |
| 3 | +// |
| 4 | +// Copyright (C) 2014-2021 Marcin Krzyżanowski < [email protected]> |
| 5 | +// This software is provided 'as-is', without any express or implied warranty. |
| 6 | +// |
| 7 | +// In no event will the authors be held liable for any damages arising from the use of this software. |
| 8 | +// |
| 9 | +// 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: |
| 10 | +// |
| 11 | +// - 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. |
| 12 | +// - Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. |
| 13 | +// - This notice may not be removed or altered from any source or binary distribution. |
| 14 | +// |
| 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 | + |
| 20 | +/// EMSA PKCS1 v1.5 Padding Scheme |
| 21 | +/// |
| 22 | +/// The EMSA Version of the PKCS1 v1.5 padding scheme is **deterministic** (it pads the messages contents with 255 value bytes) |
| 23 | +/// ``` |
| 24 | +/// // The returned structure |
| 25 | +/// // - PS is the applied padding |
| 26 | +/// // - M is your original Message |
| 27 | +/// EM = 0x00 || 0x01 || PS || 0x00 || M. |
| 28 | +/// ``` |
| 29 | +/// - Note: This Padding scheme is intended to be used for encoding RSA Signatures |
| 30 | +struct EMSAPKCS1v15Padding: PaddingProtocol { |
| 31 | + |
| 32 | + init() { |
| 33 | + } |
| 34 | + |
| 35 | + @inlinable |
| 36 | + func add(to bytes: Array<UInt8>, blockSize: Int) -> Array<UInt8> { |
| 37 | + var r = blockSize - ((bytes.count + 3) % blockSize) |
| 38 | + if r <= 0 { r = blockSize - 3 } |
| 39 | + |
| 40 | + return [0x00, 0x01] + Array<UInt8>(repeating: 0xFF, count: r) + [0x00] + bytes |
| 41 | + } |
| 42 | + |
| 43 | + @inlinable |
| 44 | + func remove(from bytes: Array<UInt8>, blockSize _: Int?) -> Array<UInt8> { |
| 45 | + assert(!bytes.isEmpty, "Need bytes to remove padding") |
| 46 | + |
| 47 | + assert(bytes.prefix(2) == [0x00, 0x01], "Invalid padding prefix") |
| 48 | + |
| 49 | + guard let paddingLength = bytes.dropFirst(2).firstIndex(of: 0x00) else { return bytes } |
| 50 | + |
| 51 | + guard (paddingLength + 1) <= bytes.count else { return bytes } |
| 52 | + |
| 53 | + return Array(bytes[(paddingLength + 1)...]) |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +/// EME PKCS1 v1.5 Padding Scheme |
| 58 | +/// |
| 59 | +/// The EME Version of the PKCS1 v1.5 padding scheme is **non deterministic** (it pads the messages contents with psuedo-random bytes) |
| 60 | +/// ``` |
| 61 | +/// // The returned structure |
| 62 | +/// // - PS is the applied padding |
| 63 | +/// // - M is your original Message |
| 64 | +/// EM = 0x00 || 0x02 || PS || 0x00 || M. |
| 65 | +/// ``` |
| 66 | +/// - Note: This Padding scheme is intended to be used for encoding messages before RSA Encryption |
| 67 | +struct EMEPKCS1v15Padding: PaddingProtocol { |
| 68 | + |
| 69 | + init() { |
| 70 | + } |
| 71 | + |
| 72 | + @inlinable |
| 73 | + func add(to bytes: Array<UInt8>, blockSize: Int) -> Array<UInt8> { |
| 74 | + var r = blockSize - ((bytes.count + 3) % blockSize) |
| 75 | + if r <= 0 { r = blockSize - 3 } |
| 76 | + |
| 77 | + return [0x00, 0x02] + (0..<r).map { _ in UInt8.random(in: 1...UInt8.max) } + [0x00] + bytes |
| 78 | + } |
| 79 | + |
| 80 | + @inlinable |
| 81 | + func remove(from bytes: Array<UInt8>, blockSize _: Int?) -> Array<UInt8> { |
| 82 | + assert(!bytes.isEmpty, "Need bytes to remove padding") |
| 83 | + |
| 84 | + assert(bytes.prefix(2) == [0x00, 0x02], "Invalid padding prefix") |
| 85 | + |
| 86 | + guard let paddingLength = bytes.dropFirst(2).firstIndex(of: 0x00) else { return bytes } |
| 87 | + |
| 88 | + guard (paddingLength + 1) <= bytes.count else { return bytes } |
| 89 | + |
| 90 | + return Array(bytes[(paddingLength + 1)...]) |
| 91 | + } |
| 92 | +} |
0 commit comments