@@ -43,28 +43,64 @@ namespace ack {
43
43
};
44
44
constexpr size_t pkcs1_v1_5_t_sha512_size = sha512_digest_info_prefix.size() + sizeof (hash512);
45
45
static_assert ( pkcs1_v1_5_t_sha512_size == 83 );
46
- }
47
46
47
+ /* *
48
+ * Functions check if signature representative s <= n - 1.
49
+ * @note function expects s to bi positive integer.
50
+ *
51
+ * @param s - signature representative
52
+ * @param n - public key modulus
53
+ * @return true if s < n else false.
54
+ */
55
+ inline bool is_s_valid (const bytes_view& s, std::span<const uint8_t > n) {
56
+ // Skip leading zeros of s
57
+ size_t sofs = 0 ;
58
+ while (sofs < s.size () && s[sofs] == 0x00 ) {
59
+ ++sofs;
60
+ }
48
61
49
- void uECC_vli_clear (uint32_t *vli, uint32_t num_words) {
50
- uint32_t i;
51
- for (i = 0 ; i < num_words; ++i) {
52
- vli[i] = 0 ;
53
- }
54
- }
55
- void uECC_vli_bytesToNative (uint32_t *native,
56
- const uint8_t *bytes,
57
- int num_bytes) {
58
- int i;
59
- uECC_vli_clear (native, (num_bytes + (sizeof (uint32_t ) - 1 )) / sizeof (uint32_t ));
60
- for (i = 0 ; i < num_bytes; ++i) {
61
- unsigned b = num_bytes - 1 - i;
62
- native[b / sizeof (uint32_t )] |=
63
- (uint32_t )bytes[i] << (8 * (b % sizeof (uint32_t )));
62
+ // Check if s is zero
63
+ if ( sofs == s.size () ) {
64
+ return true ;
65
+ }
66
+
67
+ // Skip leading zeros of n
68
+ size_t nofs = 0 ;
69
+ while (nofs < n.size () && n[nofs] == 0x00 ) {
70
+ ++nofs;
71
+ }
72
+
73
+ // Check if s is smaller than nofs
74
+ if (sofs < nofs) {
75
+ return true ;
76
+ }
77
+
78
+ // Check if s is greater than n
79
+ if ( ( s.size () - sofs ) > ( n.size () - nofs ) ) {
80
+ return false ;
81
+ }
82
+
83
+ // Check if s is smaller than n
84
+ if ( ( s.size () - sofs ) < ( n.size () - nofs ) ) {
85
+ return true ;
86
+ }
87
+
88
+ // Compare the remaining bytes (s.size() == n.size())
89
+ #pragma unroll
90
+ for (; sofs < s.size (); ++sofs, ++nofs) {
91
+ if (s[sofs] < n[nofs]) {
92
+ return true ;
93
+ }
94
+ else if (s[sofs] > n[nofs]) {
95
+ return false ;
96
+ }
97
+ }
98
+
99
+ // s == n
100
+ return false ;
64
101
}
65
102
}
66
103
67
-
68
104
/* *
69
105
* Returns result of modular exponentiation.
70
106
* @param base - base byte array
@@ -105,42 +141,6 @@ namespace ack {
105
141
106
142
auto res = rsa_mod_exp_sw ( (const uint8_t *)base, base_len, prop, (uint8_t *)out );
107
143
rsa_free_key_prop ( prop );
108
-
109
- // assert(false);
110
- // using rsa_int = bigint<8192>;
111
- // rsa_int bn_base;
112
-
113
- // // std::array<uint32_t, 32> aa_base;
114
- // // uECC_vli_bytesToNative(aa_base.data(), (const uint8_t*)base, base_len);
115
- // // bn_base.set_array(aa_base.data(), aa_base.size());
116
-
117
- // if (!bn_base.set_bytes(bytes_view{ reinterpret_cast<const byte_t*>(base), base_len })) {
118
- // return 0;
119
- // }
120
-
121
- // bigint<32> bn_exp;
122
- // // // std::array<uint32_t, 1> aa_exp;
123
- // // // uECC_vli_bytesToNative(aa_exp.data(), (const uint8_t*)exponent, exponent_len);
124
- // // // bn_exp.set_array(aa_exp.data(), aa_exp.size());
125
- // if (!bn_exp.set_bytes(bytes_view{ reinterpret_cast<const byte_t*>(exponent), exponent_len })) {
126
- // return 0;
127
- // }
128
-
129
- // //constexpr word_t expp = 555;
130
-
131
- // rsa_int bn_mod;
132
- // // std::array<uint32_t, 32> aa_mod;
133
- // // uECC_vli_bytesToNative(aa_mod.data(), (const uint8_t*)modulus, modulus_len);
134
- // // bn_mod.set_array(aa_mod.data(), aa_mod.size());
135
- // if (!bn_mod.set_bytes(bytes_view{ reinterpret_cast<const byte_t*>(modulus), modulus_len })) {
136
- // return 0;
137
- // }
138
-
139
- // if (!bn_base.mod_exp(bn_exp, bn_mod)) {
140
- // return 0;
141
- // }
142
-
143
- // return bn_base.get_bytes(std::span<byte_t>{ reinterpret_cast<byte_t*>(out), out_len }) ? base_len : 0;
144
144
#endif
145
145
return res == 0 ? base_len : 0 ;
146
146
}
@@ -171,13 +171,15 @@ namespace ack {
171
171
return result;
172
172
}
173
173
174
- [[nodiscard]] inline bytes rsavp1 (const rsa_public_key_view pub_key, const bytes_view& signature) {
175
- // Note: Missing check for signature representative (integer between 0 and n - 1)
174
+ [[nodiscard]] inline bytes rsavp1 (const rsa_public_key_view pub_key, const bytes_view signature) {
175
+ if ( !detail::is_s_valid ( signature, pub_key.modulus ) ) {
176
+ return bytes ();
177
+ }
176
178
return powm ( signature, pub_key.exponent , pub_key.modulus );
177
179
}
178
180
179
181
template <size_t t_len, typename Lambda>
180
- [[nodiscard]] bool rsassa_pkcs1_v1_5_verify (const rsa_public_key_view& pub_key, const bytes_view& signature, Lambda&& gen_t )
182
+ [[nodiscard]] bool rsassa_pkcs1_v1_5_verify (const rsa_public_key_view& pub_key, const bytes_view signature, Lambda&& gen_t )
181
183
{
182
184
if ( signature.size () != pub_key.modulus .size () ) {
183
185
ACK_LOG_DEBUG ( " [ERROR] rsassa_pkcs1_v1_5_verify: invalid signature" );
0 commit comments