Skip to content

Commit ce9edf9

Browse files
committed
Added EME and EMSA PKCS1v15 Padding Schemes
1 parent 0e41a8f commit ce9edf9

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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

Comments
 (0)