Line | Count | Source (jump to first uncovered line) |
1 | | // oaep.cpp - originally written and placed in the public domain by Wei Dai |
2 | | |
3 | | #include "pch.h" |
4 | | |
5 | | #ifndef CRYPTOPP_IMPORTS |
6 | | |
7 | | #include "oaep.h" |
8 | | #include "stdcpp.h" |
9 | | #include "smartptr.h" |
10 | | |
11 | | NAMESPACE_BEGIN(CryptoPP) |
12 | | |
13 | | // ******************************************************** |
14 | | |
15 | | size_t OAEP_Base::MaxUnpaddedLength(size_t paddedLength) const |
16 | 0 | { |
17 | 0 | return SaturatingSubtract(paddedLength/8, 1+2*DigestSize()); |
18 | 0 | } |
19 | | |
20 | | void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLength, byte *oaepBlock, size_t oaepBlockLen, const NameValuePairs ¶meters) const |
21 | 0 | { |
22 | 0 | CRYPTOPP_ASSERT (inputLength <= MaxUnpaddedLength(oaepBlockLen)); |
23 | | |
24 | | // convert from bit length to byte length |
25 | 0 | if (oaepBlockLen % 8 != 0) |
26 | 0 | { |
27 | 0 | oaepBlock[0] = 0; |
28 | 0 | oaepBlock++; |
29 | 0 | } |
30 | 0 | oaepBlockLen /= 8; |
31 | |
|
32 | 0 | member_ptr<HashTransformation> pHash(NewHash()); |
33 | 0 | const size_t hLen = pHash->DigestSize(); |
34 | 0 | const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; |
35 | 0 | byte *const maskedSeed = oaepBlock; |
36 | 0 | byte *const maskedDB = oaepBlock+seedLen; |
37 | |
|
38 | 0 | ConstByteArrayParameter encodingParameters; |
39 | 0 | parameters.GetValue(Name::EncodingParameters(), encodingParameters); |
40 | | |
41 | | // DB = pHash || 00 ... || 01 || M |
42 | 0 | pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()); |
43 | 0 | std::memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1); |
44 | 0 | maskedDB[dbLen-inputLength-1] = 0x01; |
45 | 0 | std::memcpy(maskedDB+dbLen-inputLength, input, inputLength); |
46 | |
|
47 | 0 | rng.GenerateBlock(maskedSeed, seedLen); |
48 | 0 | member_ptr<MaskGeneratingFunction> pMGF(NewMGF()); |
49 | 0 | pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); |
50 | 0 | pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); |
51 | 0 | } |
52 | | |
53 | | DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, size_t oaepBlockLen, byte *output, const NameValuePairs ¶meters) const |
54 | 0 | { |
55 | 0 | bool invalid = false; |
56 | | |
57 | | // convert from bit length to byte length |
58 | 0 | if (oaepBlockLen % 8 != 0) |
59 | 0 | { |
60 | 0 | invalid = (oaepBlock[0] != 0) || invalid; |
61 | 0 | oaepBlock++; |
62 | 0 | } |
63 | 0 | oaepBlockLen /= 8; |
64 | |
|
65 | 0 | member_ptr<HashTransformation> pHash(NewHash()); |
66 | 0 | const size_t hLen = pHash->DigestSize(); |
67 | 0 | const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; |
68 | |
|
69 | 0 | invalid = (oaepBlockLen < 2*hLen+1) || invalid; |
70 | |
|
71 | 0 | SecByteBlock t(oaepBlock, oaepBlockLen); |
72 | 0 | byte *const maskedSeed = t; |
73 | 0 | byte *const maskedDB = t+seedLen; |
74 | |
|
75 | 0 | member_ptr<MaskGeneratingFunction> pMGF(NewMGF()); |
76 | 0 | pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); |
77 | 0 | pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); |
78 | |
|
79 | 0 | ConstByteArrayParameter encodingParameters; |
80 | 0 | parameters.GetValue(Name::EncodingParameters(), encodingParameters); |
81 | | |
82 | | // DB = pHash' || 00 ... || 01 || M |
83 | 0 | byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01); |
84 | 0 | invalid = (M == maskedDB+dbLen) || invalid; |
85 | 0 | invalid = (FindIfNot(maskedDB+hLen, M, byte(0)) != M) || invalid; |
86 | 0 | invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid; |
87 | |
|
88 | 0 | if (invalid) |
89 | 0 | return DecodingResult(); |
90 | | |
91 | 0 | M++; |
92 | 0 | std::memcpy(output, M, maskedDB+dbLen-M); |
93 | 0 | return DecodingResult(maskedDB+dbLen-M); |
94 | 0 | } |
95 | | |
96 | | NAMESPACE_END |
97 | | |
98 | | #endif |