185b528e0SShwetha/*
285b528e0SShwetha * pot_util.h -- Proof Of Transit Utility Header
385b528e0SShwetha *
485b528e0SShwetha * Copyright (c) 2016 Cisco and/or its affiliates.
585b528e0SShwetha * Licensed under the Apache License, Version 2.0 (the "License");
685b528e0SShwetha * you may not use this file except in compliance with the License.
785b528e0SShwetha * You may obtain a copy of the License at:
885b528e0SShwetha *
985b528e0SShwetha *     http://www.apache.org/licenses/LICENSE-2.0
1085b528e0SShwetha *
1185b528e0SShwetha * Unless required by applicable law or agreed to in writing, software
1285b528e0SShwetha * distributed under the License is distributed on an "AS IS" BASIS,
1385b528e0SShwetha * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1485b528e0SShwetha * See the License for the specific language governing permissions and
1585b528e0SShwetha * limitations under the License.
1685b528e0SShwetha */
1785b528e0SShwetha
1885b528e0SShwetha#ifndef include_vnet_pot_util_h
1985b528e0SShwetha#define include_vnet_pot_util_h
2085b528e0SShwetha
2185b528e0SShwetha#include <vnet/ip/ip6_hop_by_hop.h>
2285b528e0SShwetha#define debug_ioam debug_ioam_fn
2385b528e0SShwetha/* Dont change this size 256. This is there across multiple components */
2485b528e0SShwetha#define PATH_NAME_SIZE  256
2585b528e0SShwetha
2685b528e0SShwetha/* Ring size. this should be same as the one in ODL. Do not change this
2785b528e0SShwetha   without change in ODL. */
2885b528e0SShwetha#define MAX_POT_PROFILES 2
2985b528e0SShwetha
3085b528e0SShwetha/**
3185b528e0SShwetha * Usage:
3285b528e0SShwetha *
3385b528e0SShwetha * On any node that participates in Proof of Transit:
3485b528e0SShwetha *
3585b528e0SShwetha * Step 1: Initialize this library by calling pot_init()
3685b528e0SShwetha * Step 2: Setup a proof of transit  profile that contains all the parameters needed to compute cumulative:
3785b528e0SShwetha *         Call these functions:
3885b528e0SShwetha *         pot_profile_find
3985b528e0SShwetha *         pot_profile_create
4085b528e0SShwetha *         pot_profile_set_bit_mask - To setup how large we want the numbers used in the computation and random number <= 64 bits
4185b528e0SShwetha * Step 2a: For validator do this:
4285b528e0SShwetha *          pot_set_validator
4385b528e0SShwetha * Step 2b: On initial node enable the profile to be used:
4485b528e0SShwetha *          pot_profile_set_active / pot_profile_get_active will return the profile
4585b528e0SShwetha * Step 3a: At the initial node to generate Random number that will be read by all other nodes:
4685b528e0SShwetha *          pot_generate_random
4785b528e0SShwetha * Step 3b: At all nodes including initial and verifier call this to compute cumulative:
4885b528e0SShwetha *          pot_update_cumulative
4985b528e0SShwetha * Step 4: At the verifier:
5085b528e0SShwetha *         pot_validate
5185b528e0SShwetha *
5285b528e0SShwetha */
5385b528e0SShwetha
5485b528e0SShwethatypedef struct pot_profile_
5585b528e0SShwetha{
5685b528e0SShwetha    u8 id : 1;
5785b528e0SShwetha    u8 valid : 1;
5885b528e0SShwetha    u8 in_use : 1;
5985b528e0SShwetha    u64 random;
6085b528e0SShwetha    u8 validator;
6185b528e0SShwetha    u64 secret_key;
6285b528e0SShwetha    u64 secret_share;
6385b528e0SShwetha    u64 prime;
6485b528e0SShwetha    u64 lpc;
6585b528e0SShwetha    u64 poly_pre_eval;
6685b528e0SShwetha    u64 bit_mask;
6785b528e0SShwetha    u64 limit;
6885b528e0SShwetha    double primeinv;
6985b528e0SShwetha    u64 total_pkts_using_this_profile;
7085b528e0SShwetha} pot_profile;
7185b528e0SShwetha
7285b528e0SShwethatypedef struct {
7385b528e0SShwetha    /* Name of the default profile list in use*/
7485b528e0SShwetha    u8 *profile_list_name;
7585b528e0SShwetha    pot_profile profile_list[MAX_POT_PROFILES];
7685b528e0SShwetha    /* number of profiles in the list */
7785b528e0SShwetha    u8 active_profile_id : 1;
7885b528e0SShwetha
7985b528e0SShwetha    /* API message ID base */
8085b528e0SShwetha    u16 msg_id_base;
8185b528e0SShwetha
8285b528e0SShwetha    /* convenience */
8385b528e0SShwetha    vlib_main_t * vlib_main;
8485b528e0SShwetha    vnet_main_t * vnet_main;
8585b528e0SShwetha} pot_main_t;
8685b528e0SShwetha
8785b528e0SShwethaextern pot_main_t pot_main;
8885b528e0SShwetha
8985b528e0SShwetha/*
9085b528e0SShwetha * Initialize proof of transit
9185b528e0SShwetha */
9285b528e0SShwethaint pot_util_init(void);
9385b528e0SShwethavoid pot_profile_list_init(u8 * name);
9485b528e0SShwetha
9585b528e0SShwetha
9685b528e0SShwetha/*
9785b528e0SShwetha * Find a pot profile by ID
9885b528e0SShwetha */
9985b528e0SShwethapot_profile *pot_profile_find(u8 id);
10085b528e0SShwetha
10185b528e0SShwethastatic inline u16 pot_profile_get_id(pot_profile * profile)
10285b528e0SShwetha{
10385b528e0SShwetha    if (profile)
10485b528e0SShwetha    {
10585b528e0SShwetha        return (profile->id);
10685b528e0SShwetha    }
10785b528e0SShwetha    return (0);
10885b528e0SShwetha}
10985b528e0SShwetha
11085b528e0SShwetha/* setup and clean up profile */
11185b528e0SShwethaint pot_profile_create(pot_profile * profile, u64 prime,
11285b528e0SShwetha    u64 poly2, u64 lpc, u64 secret_share);
11385b528e0SShwetha/*
11485b528e0SShwetha * Setup profile as a validator
11585b528e0SShwetha */
11685b528e0SShwethaint pot_set_validator(pot_profile * profile, u64 key);
11785b528e0SShwetha
11885b528e0SShwetha/*
11985b528e0SShwetha * Setup max bits to be used for random number generation
12085b528e0SShwetha */
12185b528e0SShwetha#define MAX_BITS 64
12285b528e0SShwethaint pot_profile_set_bit_mask(pot_profile * profile, u16 bits);
12385b528e0SShwetha
12485b528e0SShwetha/*
12585b528e0SShwetha * Given a random and cumulative compute the new cumulative for a given profile
12685b528e0SShwetha */
12785b528e0SShwethau64 pot_update_cumulative(pot_profile * profile, u64 cumulative, u64 random);
12885b528e0SShwetha
12985b528e0SShwetha/*
13085b528e0SShwetha * return True if the cumulative matches secret from a profile
13185b528e0SShwetha */
13285b528e0SShwethau8 pot_validate(pot_profile * profile, u64 cumulative, u64 random);
13385b528e0SShwetha
13485b528e0SShwetha/*
13585b528e0SShwetha * Utility function to get random number per pack
13685b528e0SShwetha */
13785b528e0SShwethau64 pot_generate_random(pot_profile * profile);
13885b528e0SShwetha
13985b528e0SShwetha
14085b528e0SShwethaextern void clear_pot_profiles();
14185b528e0SShwethaextern int pot_profile_list_is_enabled(u8 *name);
14285b528e0SShwetha
14385b528e0SShwethastatic inline u8 pot_is_decap(pot_profile * p)
14485b528e0SShwetha{
14585b528e0SShwetha    return (p->validator == 1);
14685b528e0SShwetha}
14785b528e0SShwetha
14885b528e0SShwethastatic inline int pot_profile_set_active (u8 id)
14985b528e0SShwetha{
15085b528e0SShwetha    pot_main_t *sm = &pot_main;
15185b528e0SShwetha    pot_profile *profile = NULL;
15285b528e0SShwetha    pot_profile *current_active_prof = NULL;
15385b528e0SShwetha
15485b528e0SShwetha    current_active_prof = pot_profile_find(sm->active_profile_id);
15585b528e0SShwetha    profile = pot_profile_find(id);
15685b528e0SShwetha    if (profile && profile->valid) {
15785b528e0SShwetha        sm->active_profile_id = id;
15885b528e0SShwetha	current_active_prof->in_use = 0;
15985b528e0SShwetha	profile->in_use = 1;
16085b528e0SShwetha	return(0);
16185b528e0SShwetha    }
16285b528e0SShwetha    return(-1);
16385b528e0SShwetha}
16485b528e0SShwethastatic inline u8 pot_profile_get_active_id (void)
16585b528e0SShwetha{
16685b528e0SShwetha    pot_main_t *sm = &pot_main;
16785b528e0SShwetha    return (sm->active_profile_id);
16885b528e0SShwetha}
16985b528e0SShwetha
17085b528e0SShwethastatic inline pot_profile * pot_profile_get_active (void)
17185b528e0SShwetha{
17285b528e0SShwetha    pot_main_t *sm = &pot_main;
17385b528e0SShwetha    pot_profile *profile = NULL;
17485b528e0SShwetha    profile = pot_profile_find(sm->active_profile_id);
17585b528e0SShwetha    if (profile && profile->in_use)
17685b528e0SShwetha        return(profile);
17785b528e0SShwetha    return (NULL);
17885b528e0SShwetha}
17985b528e0SShwetha
18085b528e0SShwethastatic inline void pot_profile_reset_usage_stats (pot_profile *pow)
18185b528e0SShwetha{
18285b528e0SShwetha  if (pow) {
18385b528e0SShwetha    pow->total_pkts_using_this_profile = 0;
18485b528e0SShwetha  }
18585b528e0SShwetha}
18685b528e0SShwetha
18785b528e0SShwethastatic inline void pot_profile_incr_usage_stats (pot_profile *pow)
18885b528e0SShwetha{
18985b528e0SShwetha  if (pow) {
19085b528e0SShwetha    pow->total_pkts_using_this_profile++;
19185b528e0SShwetha  }
19285b528e0SShwetha}
19385b528e0SShwetha
19485b528e0SShwetha
19585b528e0SShwetha#endif
196