1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "../ssl_local.h" 11e1051a39Sopenharmony_ci#include "record_local.h" 12e1051a39Sopenharmony_ci 13e1051a39Sopenharmony_ci/* mod 128 saturating subtract of two 64-bit values in big-endian order */ 14e1051a39Sopenharmony_cistatic int satsub64be(const unsigned char *v1, const unsigned char *v2) 15e1051a39Sopenharmony_ci{ 16e1051a39Sopenharmony_ci int64_t ret; 17e1051a39Sopenharmony_ci uint64_t l1, l2; 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ci n2l8(v1, l1); 20e1051a39Sopenharmony_ci n2l8(v2, l2); 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ci ret = l1 - l2; 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci /* We do not permit wrap-around */ 25e1051a39Sopenharmony_ci if (l1 > l2 && ret < 0) 26e1051a39Sopenharmony_ci return 128; 27e1051a39Sopenharmony_ci else if (l2 > l1 && ret > 0) 28e1051a39Sopenharmony_ci return -128; 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci if (ret > 128) 31e1051a39Sopenharmony_ci return 128; 32e1051a39Sopenharmony_ci else if (ret < -128) 33e1051a39Sopenharmony_ci return -128; 34e1051a39Sopenharmony_ci else 35e1051a39Sopenharmony_ci return (int)ret; 36e1051a39Sopenharmony_ci} 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ciint dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) 39e1051a39Sopenharmony_ci{ 40e1051a39Sopenharmony_ci int cmp; 41e1051a39Sopenharmony_ci unsigned int shift; 42e1051a39Sopenharmony_ci const unsigned char *seq = s->rlayer.read_sequence; 43e1051a39Sopenharmony_ci 44e1051a39Sopenharmony_ci cmp = satsub64be(seq, bitmap->max_seq_num); 45e1051a39Sopenharmony_ci if (cmp > 0) { 46e1051a39Sopenharmony_ci SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq); 47e1051a39Sopenharmony_ci return 1; /* this record in new */ 48e1051a39Sopenharmony_ci } 49e1051a39Sopenharmony_ci shift = -cmp; 50e1051a39Sopenharmony_ci if (shift >= sizeof(bitmap->map) * 8) 51e1051a39Sopenharmony_ci return 0; /* stale, outside the window */ 52e1051a39Sopenharmony_ci else if (bitmap->map & (1UL << shift)) 53e1051a39Sopenharmony_ci return 0; /* record previously received */ 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq); 56e1051a39Sopenharmony_ci return 1; 57e1051a39Sopenharmony_ci} 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_civoid dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) 60e1051a39Sopenharmony_ci{ 61e1051a39Sopenharmony_ci int cmp; 62e1051a39Sopenharmony_ci unsigned int shift; 63e1051a39Sopenharmony_ci const unsigned char *seq = RECORD_LAYER_get_read_sequence(&s->rlayer); 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci cmp = satsub64be(seq, bitmap->max_seq_num); 66e1051a39Sopenharmony_ci if (cmp > 0) { 67e1051a39Sopenharmony_ci shift = cmp; 68e1051a39Sopenharmony_ci if (shift < sizeof(bitmap->map) * 8) 69e1051a39Sopenharmony_ci bitmap->map <<= shift, bitmap->map |= 1UL; 70e1051a39Sopenharmony_ci else 71e1051a39Sopenharmony_ci bitmap->map = 1UL; 72e1051a39Sopenharmony_ci memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE); 73e1051a39Sopenharmony_ci } else { 74e1051a39Sopenharmony_ci shift = -cmp; 75e1051a39Sopenharmony_ci if (shift < sizeof(bitmap->map) * 8) 76e1051a39Sopenharmony_ci bitmap->map |= 1UL << shift; 77e1051a39Sopenharmony_ci } 78e1051a39Sopenharmony_ci} 79