/src/nss/lib/freebl/verified/Hacl_P521.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* MIT License |
2 | | * |
3 | | * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation |
4 | | * Copyright (c) 2022-2023 HACL* Contributors |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | | * of this software and associated documentation files (the "Software"), to deal |
8 | | * in the Software without restriction, including without limitation the rights |
9 | | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | | * copies of the Software, and to permit persons to whom the Software is |
11 | | * furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included in all |
14 | | * copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 | | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
22 | | * SOFTWARE. |
23 | | */ |
24 | | |
25 | | #include "Hacl_P521.h" |
26 | | |
27 | | #include "internal/Hacl_Krmllib.h" |
28 | | #include "internal/Hacl_Bignum_Base.h" |
29 | | |
30 | | static inline uint64_t |
31 | | bn_is_eq_mask(uint64_t *x, uint64_t *y) |
32 | 0 | { |
33 | 0 | uint64_t mask = (uint64_t)0xFFFFFFFFFFFFFFFFU; |
34 | 0 | KRML_MAYBE_FOR9(i, |
35 | 0 | (uint32_t)0U, |
36 | 0 | (uint32_t)9U, |
37 | 0 | (uint32_t)1U, |
38 | 0 | uint64_t uu____0 = FStar_UInt64_eq_mask(x[i], y[i]); |
39 | 0 | mask = uu____0 & mask;); |
40 | 0 | uint64_t mask1 = mask; |
41 | 0 | return mask1; |
42 | 0 | } |
43 | | |
44 | | static inline uint64_t |
45 | | bn_sub(uint64_t *a, uint64_t *b, uint64_t *c) |
46 | 0 | { |
47 | 0 | uint64_t c1 = (uint64_t)0U; |
48 | 0 | KRML_MAYBE_FOR2(i, |
49 | 0 | (uint32_t)0U, |
50 | 0 | (uint32_t)2U, |
51 | 0 | (uint32_t)1U, |
52 | 0 | uint64_t t1 = b[(uint32_t)4U * i]; |
53 | 0 | uint64_t t20 = c[(uint32_t)4U * i]; |
54 | 0 | uint64_t *res_i0 = a + (uint32_t)4U * i; |
55 | 0 | c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t20, res_i0); |
56 | 0 | uint64_t t10 = b[(uint32_t)4U * i + (uint32_t)1U]; |
57 | 0 | uint64_t t21 = c[(uint32_t)4U * i + (uint32_t)1U]; |
58 | 0 | uint64_t *res_i1 = a + (uint32_t)4U * i + (uint32_t)1U; |
59 | 0 | c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t10, t21, res_i1); |
60 | 0 | uint64_t t11 = b[(uint32_t)4U * i + (uint32_t)2U]; |
61 | 0 | uint64_t t22 = c[(uint32_t)4U * i + (uint32_t)2U]; |
62 | 0 | uint64_t *res_i2 = a + (uint32_t)4U * i + (uint32_t)2U; |
63 | 0 | c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t11, t22, res_i2); |
64 | 0 | uint64_t t12 = b[(uint32_t)4U * i + (uint32_t)3U]; |
65 | 0 | uint64_t t2 = c[(uint32_t)4U * i + (uint32_t)3U]; |
66 | 0 | uint64_t *res_i = a + (uint32_t)4U * i + (uint32_t)3U; |
67 | 0 | c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t12, t2, res_i);); |
68 | 0 | { |
69 | 0 | uint64_t t1 = b[8U]; |
70 | 0 | uint64_t t2 = c[8U]; |
71 | 0 | uint64_t *res_i = a + (uint32_t)8U; |
72 | 0 | c1 = Lib_IntTypes_Intrinsics_sub_borrow_u64(c1, t1, t2, res_i); |
73 | 0 | } |
74 | 0 | uint64_t c10 = c1; |
75 | 0 | return c10; |
76 | 0 | } |
77 | | |
78 | | static inline void |
79 | | bn_from_bytes_be(uint64_t *a, uint8_t *b) |
80 | 0 | { |
81 | 0 | uint8_t tmp[72U] = { 0U }; |
82 | 0 | memcpy(tmp + (uint32_t)6U, b, (uint32_t)66U * sizeof(uint8_t)); |
83 | 0 | KRML_MAYBE_FOR9(i, |
84 | 0 | (uint32_t)0U, |
85 | 0 | (uint32_t)9U, |
86 | 0 | (uint32_t)1U, |
87 | 0 | uint64_t *os = a; |
88 | 0 | uint64_t u = load64_be(tmp + ((uint32_t)9U - i - (uint32_t)1U) * (uint32_t)8U); |
89 | 0 | uint64_t x = u; |
90 | 0 | os[i] = x;); |
91 | 0 | } |
92 | | |
93 | | static inline void |
94 | | p521_make_order(uint64_t *n) |
95 | 0 | { |
96 | 0 | n[0U] = (uint64_t)0xbb6fb71e91386409U; |
97 | 0 | n[1U] = (uint64_t)0x3bb5c9b8899c47aeU; |
98 | 0 | n[2U] = (uint64_t)0x7fcc0148f709a5d0U; |
99 | 0 | n[3U] = (uint64_t)0x51868783bf2f966bU; |
100 | 0 | n[4U] = (uint64_t)0xfffffffffffffffaU; |
101 | 0 | n[5U] = (uint64_t)0xffffffffffffffffU; |
102 | 0 | n[6U] = (uint64_t)0xffffffffffffffffU; |
103 | 0 | n[7U] = (uint64_t)0xffffffffffffffffU; |
104 | 0 | n[8U] = (uint64_t)0x1ffU; |
105 | 0 | } |
106 | | |
107 | | /** |
108 | | Private key validation. |
109 | | |
110 | | The function returns `true` if a private key is valid and `false` otherwise. |
111 | | |
112 | | The argument `private_key` points to 66 bytes of valid memory, i.e., uint8_t[66]. |
113 | | |
114 | | The private key is valid: |
115 | | • 0 < `private_key` < the order of the curve |
116 | | */ |
117 | | bool |
118 | | Hacl_P521_validate_private_key(uint8_t *private_key) |
119 | 0 | { |
120 | 0 | uint64_t bn_sk[9U] = { 0U }; |
121 | 0 | bn_from_bytes_be(bn_sk, private_key); |
122 | 0 | uint64_t tmp[9U] = { 0U }; |
123 | 0 | p521_make_order(tmp); |
124 | 0 | uint64_t c = bn_sub(tmp, bn_sk, tmp); |
125 | 0 | uint64_t is_lt_order = (uint64_t)0U - c; |
126 | 0 | uint64_t bn_zero[9U] = { 0U }; |
127 | 0 | uint64_t res = bn_is_eq_mask(bn_sk, bn_zero); |
128 | 0 | uint64_t is_eq_zero = res; |
129 | 0 | uint64_t res0 = is_lt_order & ~is_eq_zero; |
130 | 0 | return res0 == (uint64_t)0xFFFFFFFFFFFFFFFFU; |
131 | 0 | } |