dtls1_bitmap.c 2.1 KB

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