api_b64.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
  2. /*
  3. * Copyright 2017 Red Hat, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include <jose/jose.h>
  18. #include <limits.h>
  19. #include <string.h>
  20. #include <assert.h>
  21. #define NBYTES(size) ((((unsigned long long) size) + 1ULL) / 8ULL)
  22. #ifdef __MINGW32__
  23. #define fprintf __mingw_fprintf
  24. #endif
  25. union encoding {
  26. uint32_t idx;
  27. uint8_t enc[4];
  28. };
  29. static inline void
  30. set(uint8_t *val, uint32_t idx)
  31. {
  32. const uint8_t n = 1 << (idx % 8);
  33. uint8_t *p = &val[idx / 8];
  34. #pragma omp atomic update
  35. *p |= n;
  36. }
  37. static inline bool
  38. get(uint8_t *val, uint32_t idx)
  39. {
  40. const uint8_t n = 1 << (idx % 8);
  41. uint8_t *p = &val[idx / 8];
  42. uint8_t v;
  43. #pragma omp atomic read
  44. v = *p;
  45. return (v & n) == n;
  46. }
  47. int
  48. main(int argc, char *argv[])
  49. {
  50. uint8_t *val = NULL;
  51. /* Ensure that all one byte encodings are invalid. */
  52. #pragma omp parallel for
  53. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  54. union encoding enc = { i };
  55. uint8_t dec[3] = {};
  56. assert(dec != NULL);
  57. assert(jose_b64_dec_buf(enc.enc, 1, dec, sizeof(dec)) == SIZE_MAX);
  58. }
  59. /* Test all two-byte encodings. */
  60. val = calloc(NBYTES(UINT32_MAX), sizeof(uint8_t));
  61. if (!val)
  62. return EXIT_FAILURE;
  63. #pragma omp parallel for shared(val)
  64. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  65. uint8_t dec[3] = { i };
  66. union encoding enc = {};
  67. assert(dec != NULL);
  68. assert(jose_b64_enc_buf(dec, 1, enc.enc, sizeof(enc.enc)) == 2);
  69. set(val, enc.idx);
  70. }
  71. #pragma omp parallel for shared(val)
  72. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  73. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  74. union encoding enc = { .enc = { i, j } };
  75. uint8_t dec[3] = {};
  76. size_t len = 0;
  77. len = get(val, enc.idx) ? 1 : SIZE_MAX;
  78. if (jose_b64_dec_buf(enc.enc, 2, dec, sizeof(dec)) != len) {
  79. fprintf(stderr, "{%hx,%hx}\"%c%c\" != %zu\n",
  80. i, j, enc.enc[0], enc.enc[1], len);
  81. assert(false);
  82. }
  83. }
  84. }
  85. free(val);
  86. /* Test all three-byte encodings. */
  87. val = calloc(NBYTES(UINT32_MAX), sizeof(uint8_t));
  88. if (!val)
  89. return EXIT_FAILURE;
  90. #pragma omp parallel for shared(val)
  91. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  92. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  93. uint8_t dec[3] = { i, j };
  94. union encoding enc = {};
  95. assert(dec != NULL);
  96. assert(jose_b64_enc_buf(dec, 2, enc.enc, sizeof(enc.enc)) == 3);
  97. set(val, enc.idx);
  98. }
  99. }
  100. #pragma omp parallel for shared(val)
  101. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  102. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  103. for (uint16_t k = 0; k <= UINT8_MAX; k++) {
  104. union encoding enc = { .enc = { i, j, k } };
  105. uint8_t dec[3] = {};
  106. size_t len = 0;
  107. len = get(val, enc.idx) ? 2 : SIZE_MAX;
  108. if (jose_b64_dec_buf(enc.enc, 3, dec, sizeof(dec)) != len) {
  109. fprintf(stderr, "{%hu,%hu,%hu}\"%c%c%c\" != %zu\n",
  110. i, j, k, enc.enc[0], enc.enc[1], enc.enc[2], len);
  111. assert(false);
  112. }
  113. }
  114. }
  115. }
  116. free(val);
  117. /* Test all four-byte encodings. */
  118. #if defined(_OPENMP) && _OPENMP >= 201107
  119. val = calloc(NBYTES(UINT32_MAX), sizeof(uint8_t));
  120. if (!val)
  121. return EXIT_FAILURE;
  122. #pragma omp parallel for shared(val)
  123. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  124. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  125. for (uint16_t k = 0; k <= UINT8_MAX; k++) {
  126. uint8_t dec[3] = { i, j, k };
  127. union encoding enc = {};
  128. assert(jose_b64_enc_buf(dec, 3, enc.enc, sizeof(enc.enc)) == 4);
  129. set(val, enc.idx);
  130. }
  131. }
  132. }
  133. #pragma omp parallel for shared(val)
  134. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  135. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  136. for (uint16_t k = 0; k <= UINT8_MAX; k++) {
  137. for (uint16_t l = 0; l <= UINT8_MAX; l++) {
  138. union encoding enc = { .enc = { i, j, k, l } };
  139. uint8_t dec[3] = {};
  140. size_t len = 0;
  141. len = get(val, enc.idx) ? 3 : SIZE_MAX;
  142. if (jose_b64_dec_buf(enc.enc, 4, dec, sizeof(dec)) != len) {
  143. fprintf(stderr, "{%hu,%hu,%hu,%hu}\"%c%c%c%c\" != %zu\n",
  144. i, j, k, l, enc.enc[0], enc.enc[1], enc.enc[2], enc.enc[3], len);
  145. assert(false);
  146. }
  147. }
  148. }
  149. }
  150. }
  151. free(val);
  152. #endif
  153. return 0;
  154. }