Path: blob/main/crypto/krb5/src/lib/gssapi/generic/t_seqstate.c
39563 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/* lib/gssapi/generic/t_seqstate.c - Test program for sequence number state */2/*3* Copyright (C) 2014 by the Massachusetts Institute of Technology.4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9*10* * Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright14* notice, this list of conditions and the following disclaimer in15* the documentation and/or other materials provided with the16* distribution.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS19* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT20* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS21* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE22* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,23* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES24* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR25* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,27* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED29* OF THE POSSIBILITY OF SUCH DAMAGE.30*/3132#include "gssapiP_generic.h"3334enum resultcode {35NOERR = GSS_S_COMPLETE,36GAP = GSS_S_GAP_TOKEN,37UNSEQ = GSS_S_UNSEQ_TOKEN,38OLD = GSS_S_OLD_TOKEN,39REPLAY = GSS_S_DUPLICATE_TOKEN40};4142enum replayflag { NO_REPLAY = 0, DO_REPLAY = 1 };43enum sequenceflag { NO_SEQUENCE = 0, DO_SEQUENCE = 1 };44enum width { NARROW = 0, WIDE = 1, BOTH = 2 };4546struct test {47uint64_t initial;48enum replayflag do_replay;49enum sequenceflag do_sequence;50enum width wide_seqnums;51size_t nseqs;52struct {53uint64_t seqnum;54enum resultcode result;55} seqs[10];56} tests[] = {57/* No replay or sequence checking. */58{5910, NO_REPLAY, NO_SEQUENCE, BOTH,604, { { 11, NOERR }, { 10, NOERR }, { 10, NOERR }, { 9, NOERR } }61},6263/* Basic sequence checking, no wraparound. */64{65100, NO_REPLAY, DO_SEQUENCE, BOTH,664, { { 100, NOERR }, { 102, GAP }, { 103, NOERR }, { 101, UNSEQ } }67},6869/* Initial gap sequence checking, no wraparound. */70{71200, NO_REPLAY, DO_SEQUENCE, BOTH,724, { { 201, GAP }, { 202, NOERR }, { 200, UNSEQ }, { 203, NOERR } }73},7475/* Sequence checking with wraparound. */76{77UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, NARROW,784, { { UINT32_MAX - 1, NOERR }, { UINT32_MAX, NOERR }, { 0, NOERR },79{ 1, NOERR } }80},81{82UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, NARROW,834, { { UINT32_MAX - 1, NOERR }, { 0, GAP }, { UINT32_MAX, UNSEQ },84{ 1, NOERR } }85},86{87UINT64_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,884, { { UINT64_MAX - 1, NOERR }, { UINT64_MAX, NOERR }, { 0, NOERR },89{ 1, NOERR } }90},91{92UINT64_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,934, { { UINT64_MAX - 1, NOERR }, { 0, GAP }, { UINT64_MAX, UNSEQ },94{ 1, NOERR } }95},9697/* 64-bit sequence checking beyond 32-bit range */98{99UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,1004, { { UINT32_MAX - 1, NOERR },101{ UINT32_MAX, NOERR },102{ (uint64_t)UINT32_MAX + 1, NOERR },103{ (uint64_t)UINT32_MAX + 2, NOERR } }104},105{106UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,1074, { { UINT32_MAX - 1, NOERR },108{ (uint64_t)UINT32_MAX + 1, GAP },109{ UINT32_MAX, UNSEQ },110{ (uint64_t)UINT32_MAX + 2, NOERR } }111},112{113UINT32_MAX - 1, NO_REPLAY, DO_SEQUENCE, WIDE,1143, { { UINT32_MAX - 1, NOERR }, { UINT32_MAX, NOERR }, { 0, GAP } }115},116117/* Replay without the replay flag set. */118{119250, NO_REPLAY, DO_SEQUENCE, BOTH,1202, { { 250, NOERR }, { 250, UNSEQ } }121},122123/* Basic replay detection with and without sequence checking. */124{1250, DO_REPLAY, DO_SEQUENCE, BOTH,12610, { { 5, GAP }, { 3, UNSEQ }, { 8, GAP }, { 3, REPLAY },127{ 0, UNSEQ }, { 0, REPLAY }, { 5, REPLAY }, { 3, REPLAY },128{ 8, REPLAY }, { 9, NOERR } }129},130{1310, DO_REPLAY, NO_SEQUENCE, BOTH,13210, { { 5, NOERR }, { 3, NOERR }, { 8, NOERR }, { 3, REPLAY },133{ 0, NOERR }, { 0, REPLAY }, { 5, REPLAY }, { 3, REPLAY },134{ 8, REPLAY }, { 9, NOERR } }135},136137/* Replay and sequence detection with wraparound. The last seqnum produces138* GAP because it is before the initial sequence number. */139{140UINT64_MAX - 5, DO_REPLAY, DO_SEQUENCE, WIDE,14110, { { UINT64_MAX, GAP }, { UINT64_MAX - 2, UNSEQ }, { 0, NOERR },142{ UINT64_MAX, REPLAY }, { UINT64_MAX, REPLAY },143{ 2, GAP }, { 0, REPLAY }, { 1, UNSEQ },144{ UINT64_MAX - 2, REPLAY }, { UINT64_MAX - 6, GAP } }145},146{147UINT32_MAX - 5, DO_REPLAY, DO_SEQUENCE, NARROW,14810, { { UINT32_MAX, GAP }, { UINT32_MAX - 2, UNSEQ }, { 0, NOERR },149{ UINT32_MAX, REPLAY }, { UINT32_MAX, REPLAY },150{ 2, GAP }, { 0, REPLAY }, { 1, UNSEQ },151{ UINT32_MAX - 2, REPLAY }, { UINT32_MAX - 6, GAP } }152},153154/* Old token edge cases. The current code can detect replays up to 64155* numbers behind the expected sequence number (1164 in this case). */156{1571000, DO_REPLAY, NO_SEQUENCE, BOTH,15810, { { 1163, NOERR }, { 1100, NOERR }, { 1100, REPLAY },159{ 1163, REPLAY }, { 1099, OLD }, { 1100, REPLAY },160{ 1150, NOERR }, { 1150, REPLAY }, { 1000, OLD },161{ 999, NOERR } }162},163};164165int166main(void)167{168size_t i, j;169enum width w;170struct test *t;171g_seqnum_state seqstate;172OM_uint32 status;173174for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {175t = &tests[i];176/* Try both widths if t->wide_seqnums is both, otherwise just one. */177for (w = NARROW; w <= WIDE; w++) {178if (t->wide_seqnums != BOTH && t->wide_seqnums != w)179continue;180if (g_seqstate_init(&seqstate, t->initial, t->do_replay,181t->do_sequence, w))182abort();183for (j = 0; j < t->nseqs; j++) {184status = g_seqstate_check(seqstate, t->seqs[j].seqnum);185if (status != t->seqs[j].result) {186fprintf(stderr, "Test %d seq %d failed: %d != %d\n",187(int)i, (int)j, status, t->seqs[j].result);188return 1;189}190}191g_seqstate_free(seqstate);192}193}194195return 0;196}197198199