Line data Source code
1 : /* 2 : * pot_util.h -- Proof Of Transit Utility Header 3 : * 4 : * Copyright (c) 2016 Cisco and/or its affiliates. 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at: 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #ifndef include_vnet_pot_util_h 19 : #define include_vnet_pot_util_h 20 : 21 : #include <vnet/ip/ip6_hop_by_hop.h> 22 : #define debug_ioam debug_ioam_fn 23 : /* Dont change this size 256. This is there across multiple components */ 24 : #define PATH_NAME_SIZE 256 25 : 26 : /* Ring size. this should be same as the one in ODL. Do not change this 27 : without change in ODL. */ 28 : #define MAX_POT_PROFILES 2 29 : 30 : /** 31 : * Usage: 32 : * 33 : * On any node that participates in Proof of Transit: 34 : * 35 : * Step 1: Initialize this library by calling pot_init() 36 : * Step 2: Setup a proof of transit profile that contains all the parameters needed to compute cumulative: 37 : * Call these functions: 38 : * pot_profile_find 39 : * pot_profile_create 40 : * pot_profile_set_bit_mask - To setup how large we want the numbers used in the computation and random number <= 64 bits 41 : * Step 2a: For validator do this: 42 : * pot_set_validator 43 : * Step 2b: On initial node enable the profile to be used: 44 : * pot_profile_set_active / pot_profile_get_active will return the profile 45 : * Step 3a: At the initial node to generate Random number that will be read by all other nodes: 46 : * pot_generate_random 47 : * Step 3b: At all nodes including initial and verifier call this to compute cumulative: 48 : * pot_update_cumulative 49 : * Step 4: At the verifier: 50 : * pot_validate 51 : * 52 : */ 53 : 54 : typedef struct pot_profile_ 55 : { 56 : u8 id : 1; 57 : u8 valid : 1; 58 : u8 in_use : 1; 59 : u64 random; 60 : u8 validator; 61 : u64 secret_key; 62 : u64 secret_share; 63 : u64 prime; 64 : u64 lpc; 65 : u64 poly_pre_eval; 66 : u64 bit_mask; 67 : u64 limit; 68 : double primeinv; 69 : u64 total_pkts_using_this_profile; 70 : } pot_profile; 71 : 72 : typedef struct { 73 : /* Name of the default profile list in use*/ 74 : u8 *profile_list_name; 75 : pot_profile profile_list[MAX_POT_PROFILES]; 76 : /* number of profiles in the list */ 77 : u8 active_profile_id : 1; 78 : 79 : /* API message ID base */ 80 : u16 msg_id_base; 81 : 82 : /* convenience */ 83 : vlib_main_t * vlib_main; 84 : vnet_main_t * vnet_main; 85 : } pot_main_t; 86 : 87 : extern pot_main_t pot_main; 88 : 89 : /* 90 : * Initialize proof of transit 91 : */ 92 : int pot_util_init(void); 93 : void pot_profile_list_init(u8 * name); 94 : 95 : 96 : /* 97 : * Find a pot profile by ID 98 : */ 99 : pot_profile *pot_profile_find(u8 id); 100 : 101 : static inline u16 pot_profile_get_id(pot_profile * profile) 102 : { 103 : if (profile) 104 : { 105 : return (profile->id); 106 : } 107 : return (0); 108 : } 109 : 110 : /* setup and clean up profile */ 111 : int pot_profile_create(pot_profile * profile, u64 prime, 112 : u64 poly2, u64 lpc, u64 secret_share); 113 : /* 114 : * Setup profile as a validator 115 : */ 116 : int pot_set_validator(pot_profile * profile, u64 key); 117 : 118 : /* 119 : * Setup max bits to be used for random number generation 120 : */ 121 : #define MAX_BITS 64 122 : int pot_profile_set_bit_mask(pot_profile * profile, u16 bits); 123 : 124 : /* 125 : * Given a random and cumulative compute the new cumulative for a given profile 126 : */ 127 : u64 pot_update_cumulative(pot_profile * profile, u64 cumulative, u64 random); 128 : 129 : /* 130 : * return True if the cumulative matches secret from a profile 131 : */ 132 : u8 pot_validate(pot_profile * profile, u64 cumulative, u64 random); 133 : 134 : /* 135 : * Utility function to get random number per pack 136 : */ 137 : u64 pot_generate_random(pot_profile * profile); 138 : 139 : 140 : extern void clear_pot_profiles(); 141 : extern int pot_profile_list_is_enabled(u8 *name); 142 : 143 0 : static inline u8 pot_is_decap(pot_profile * p) 144 : { 145 0 : return (p->validator == 1); 146 : } 147 : 148 0 : static inline int pot_profile_set_active (u8 id) 149 : { 150 0 : pot_main_t *sm = &pot_main; 151 0 : pot_profile *profile = NULL; 152 0 : pot_profile *current_active_prof = NULL; 153 : 154 0 : current_active_prof = pot_profile_find(sm->active_profile_id); 155 0 : profile = pot_profile_find(id); 156 0 : if (profile && profile->valid) { 157 0 : sm->active_profile_id = id; 158 0 : current_active_prof->in_use = 0; 159 0 : profile->in_use = 1; 160 0 : return(0); 161 : } 162 0 : return(-1); 163 : } 164 0 : static inline u8 pot_profile_get_active_id (void) 165 : { 166 0 : pot_main_t *sm = &pot_main; 167 0 : return (sm->active_profile_id); 168 : } 169 : 170 0 : static inline pot_profile * pot_profile_get_active (void) 171 : { 172 0 : pot_main_t *sm = &pot_main; 173 0 : pot_profile *profile = NULL; 174 0 : profile = pot_profile_find(sm->active_profile_id); 175 0 : if (profile && profile->in_use) 176 0 : return(profile); 177 0 : return (NULL); 178 : } 179 : 180 0 : static inline void pot_profile_reset_usage_stats (pot_profile *pow) 181 : { 182 0 : if (pow) { 183 0 : pow->total_pkts_using_this_profile = 0; 184 : } 185 0 : } 186 : 187 0 : static inline void pot_profile_incr_usage_stats (pot_profile *pow) 188 : { 189 0 : if (pow) { 190 0 : pow->total_pkts_using_this_profile++; 191 : } 192 0 : } 193 : 194 : 195 : #endif