/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 | } |