You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
4.1KB

  1. /* keysize_descriptor.c */
  2. /*
  3. This file is part of the AVR-Crypto-Lib.
  4. Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /**
  17. * \file keysize_descriptor.c
  18. * \author Daniel Otte
  19. * \email bg@nerilex.org
  20. * \date 2009-01-07
  21. * \license GPLv3 or later
  22. */
  23. #include <stdint.h>
  24. #include <stdlib.h>
  25. #include <avr/pgmspace.h>
  26. #include "keysize_descriptor.h"
  27. uint8_t is_valid_keysize_P(PGM_VOID_P ks_desc, uint16_t keysize){
  28. uint8_t type;
  29. type = pgm_read_byte(ks_desc++);
  30. if (type == KS_TYPE_TERMINATOR) {
  31. return 0;
  32. }
  33. if (type == KS_TYPE_LIST) {
  34. uint8_t items;
  35. uint16_t item;
  36. items = pgm_read_byte(ks_desc++);
  37. while (items--) {
  38. item = pgm_read_word(ks_desc);
  39. ks_desc = (uint8_t*)ks_desc + 2;
  40. if (item == keysize) {
  41. return 1;
  42. }
  43. }
  44. ks_desc = (uint8_t*)ks_desc - 2;
  45. }
  46. if (type == KS_TYPE_RANGE) {
  47. uint16_t max, min;
  48. min = pgm_read_word(ks_desc);
  49. ks_desc = (uint8_t*)ks_desc + 2;
  50. max = pgm_read_word(ks_desc);
  51. if (min <= keysize && keysize <= max) {
  52. return 1;
  53. }
  54. }
  55. if (type == KS_TYPE_ARG_RANGE) {
  56. uint16_t max, min, dist, offset;
  57. min = pgm_read_word(ks_desc);
  58. ks_desc = (uint8_t*)ks_desc + 2;
  59. max = pgm_read_word(ks_desc);
  60. ks_desc = (uint8_t*)ks_desc + 2;
  61. dist = pgm_read_word(ks_desc);
  62. ks_desc = (uint8_t*)ks_desc + 2;
  63. offset = pgm_read_word(ks_desc);
  64. if (min <= keysize && keysize <= max && (keysize % dist == offset)) {
  65. return 1;
  66. }
  67. }
  68. if (type > KS_TYPE_ARG_RANGE) {
  69. /* bad error, you may insert a big warning message here */
  70. return 0;
  71. }
  72. return is_valid_keysize_P((uint8_t*)ks_desc + 1, keysize); /* search the next record */
  73. }
  74. uint16_t get_keysize(PGM_VOID_P ks_desc){
  75. uint8_t type;
  76. uint16_t keysize;
  77. type = pgm_read_byte(ks_desc);
  78. if(type==KS_TYPE_LIST){
  79. ks_desc = (uint8_t*)ks_desc + 1;
  80. }
  81. ks_desc = (uint8_t*)ks_desc + 1;
  82. keysize = pgm_read_word(ks_desc);
  83. return keysize;
  84. }
  85. uint16_t get_keysizes(PGM_VOID_P ks_desc, uint16_t** list){
  86. uint8_t type;
  87. uint16_t items;
  88. uint8_t i;
  89. type = pgm_read_byte(ks_desc);
  90. ks_desc = (uint8_t*)ks_desc + 1;
  91. if(type==KS_TYPE_LIST){
  92. items = pgm_read_byte(ks_desc);
  93. ks_desc = (uint8_t*)ks_desc + 1;
  94. if(!*list){
  95. *list = malloc(items*2);
  96. if(!*list){
  97. return 0;
  98. }
  99. }
  100. for(i=0; i<items; ++i){
  101. ((uint16_t*)(*list))[i] = pgm_read_word(ks_desc);
  102. ks_desc = (uint8_t*)ks_desc + 2;
  103. }
  104. return items;
  105. }
  106. if(type==KS_TYPE_ARG_RANGE){
  107. uint16_t min, max, distance, offset;
  108. min = pgm_read_word(ks_desc);
  109. ks_desc = (uint8_t*)ks_desc + 2;
  110. max = pgm_read_word(ks_desc);
  111. ks_desc = (uint8_t*)ks_desc + 2;
  112. distance = pgm_read_word(ks_desc);
  113. ks_desc = (uint8_t*)ks_desc + 2;
  114. offset = pgm_read_word(ks_desc);
  115. ks_desc = (uint8_t*)ks_desc + 2;
  116. items = (max-min)/distance+1;
  117. if(min%distance!=offset){
  118. --items;
  119. min += (distance-(min%distance-offset))%distance;
  120. }
  121. if(!*list){
  122. *list = malloc(items*2);
  123. if(!*list){
  124. return 0;
  125. }
  126. }
  127. i=0;
  128. while(min<=max){
  129. ((uint16_t*)*list)[i++] = min;
  130. min += distance;
  131. }
  132. return i;
  133. }
  134. if(type==KS_TYPE_RANGE){
  135. uint16_t min, max, distance=8, offset=0;
  136. min = pgm_read_word(ks_desc);
  137. ks_desc = (uint8_t*)ks_desc + 2;
  138. max = pgm_read_word(ks_desc);
  139. items = (max-min)/distance+1;
  140. if(min%distance!=offset){
  141. --items;
  142. min += (distance-(min%distance-offset))%distance;
  143. }
  144. if(!*list){
  145. *list = malloc(items*2);
  146. if(!*list){
  147. return 0;
  148. }
  149. }
  150. i=0;
  151. while(min<=max){
  152. ((uint16_t*)*list)[i++] = min;
  153. min += distance;
  154. }
  155. return i;
  156. }
  157. return 0;
  158. }