@@ -43,28 +43,64 @@ namespace ack {
4343 };
4444 constexpr size_t pkcs1_v1_5_t_sha512_size = sha512_digest_info_prefix.size() + sizeof (hash512);
4545 static_assert ( pkcs1_v1_5_t_sha512_size == 83 );
46- }
4746
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+ }
4861
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 ;
64101 }
65102 }
66103
67-
68104 /* *
69105 * Returns result of modular exponentiation.
70106 * @param base - base byte array
@@ -105,42 +141,6 @@ namespace ack {
105141
106142 auto res = rsa_mod_exp_sw ( (const uint8_t *)base, base_len, prop, (uint8_t *)out );
107143 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;
144144 #endif
145145 return res == 0 ? base_len : 0 ;
146146 }
@@ -171,13 +171,16 @@ namespace ack {
171171 return result;
172172 }
173173
174- [[nodiscard]] inline bytes rsavp1 (const rsa_public_key_view pub_key, const bytes_view& signature) {
174+ [[nodiscard]] inline bytes rsavp1 (const rsa_public_key_view pub_key, const bytes_view signature) {
175175 // Note: Missing check for signature representative (integer between 0 and n - 1)
176+ if ( !detail::is_s_valid ( signature, pub_key.modulus ) ) {
177+ return bytes ();
178+ }
176179 return powm ( signature, pub_key.exponent , pub_key.modulus );
177180 }
178181
179182 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 )
183+ [[nodiscard]] bool rsassa_pkcs1_v1_5_verify (const rsa_public_key_view& pub_key, const bytes_view signature, Lambda&& gen_t )
181184 {
182185 if ( signature.size () != pub_key.modulus .size () ) {
183186 ACK_LOG_DEBUG ( " [ERROR] rsassa_pkcs1_v1_5_verify: invalid signature" );
0 commit comments