api_b64.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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(jose_b64_dec_buf(enc.enc, 1, dec, sizeof(dec)) == SIZE_MAX);
  57. }
  58. /* Test all two-byte encodings. */
  59. val = calloc(NBYTES(UINT32_MAX), sizeof(uint8_t));
  60. if (!val)
  61. return EXIT_FAILURE;
  62. #pragma omp parallel for shared(val)
  63. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  64. uint8_t dec[3] = { i };
  65. union encoding enc = {};
  66. assert(jose_b64_enc_buf(dec, 1, enc.enc, sizeof(enc.enc)) == 2);
  67. set(val, enc.idx);
  68. }
  69. #pragma omp parallel for shared(val)
  70. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  71. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  72. union encoding enc = { .enc = { i, j } };
  73. uint8_t dec[3] = {};
  74. size_t len = 0;
  75. len = get(val, enc.idx) ? 1 : SIZE_MAX;
  76. if (jose_b64_dec_buf(enc.enc, 2, dec, sizeof(dec)) != len) {
  77. fprintf(stderr, "{%hx,%hx}\"%c%c\" != %zu\n",
  78. i, j, enc.enc[0], enc.enc[1], len);
  79. assert(false);
  80. }
  81. }
  82. }
  83. free(val);
  84. /* Test all three-byte encodings. */
  85. val = calloc(NBYTES(UINT32_MAX), sizeof(uint8_t));
  86. if (!val)
  87. return EXIT_FAILURE;
  88. #pragma omp parallel for shared(val)
  89. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  90. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  91. uint8_t dec[3] = { i, j };
  92. union encoding enc = {};
  93. assert(jose_b64_enc_buf(dec, 2, enc.enc, sizeof(enc.enc)) == 3);
  94. set(val, enc.idx);
  95. }
  96. }
  97. #pragma omp parallel for shared(val)
  98. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  99. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  100. for (uint16_t k = 0; k <= UINT8_MAX; k++) {
  101. union encoding enc = { .enc = { i, j, k } };
  102. uint8_t dec[3] = {};
  103. size_t len = 0;
  104. len = get(val, enc.idx) ? 2 : SIZE_MAX;
  105. if (jose_b64_dec_buf(enc.enc, 3, dec, sizeof(dec)) != len) {
  106. fprintf(stderr, "{%hu,%hu,%hu}\"%c%c%c\" != %zu\n",
  107. i, j, k, enc.enc[0], enc.enc[1], enc.enc[2], len);
  108. assert(false);
  109. }
  110. }
  111. }
  112. }
  113. free(val);
  114. /* Test all four-byte encodings. */
  115. #if defined(_OPENMP) && _OPENMP >= 201107
  116. val = calloc(NBYTES(UINT32_MAX), sizeof(uint8_t));
  117. if (!val)
  118. return EXIT_FAILURE;
  119. #pragma omp parallel for shared(val)
  120. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  121. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  122. for (uint16_t k = 0; k <= UINT8_MAX; k++) {
  123. uint8_t dec[3] = { i, j, k };
  124. union encoding enc = {};
  125. assert(jose_b64_enc_buf(dec, 3, enc.enc, sizeof(enc.enc)) == 4);
  126. set(val, enc.idx);
  127. }
  128. }
  129. }
  130. #pragma omp parallel for shared(val)
  131. for (uint16_t i = 0; i <= UINT8_MAX; i++) {
  132. for (uint16_t j = 0; j <= UINT8_MAX; j++) {
  133. for (uint16_t k = 0; k <= UINT8_MAX; k++) {
  134. for (uint16_t l = 0; l <= UINT8_MAX; l++) {
  135. union encoding enc = { .enc = { i, j, k, l } };
  136. uint8_t dec[3] = {};
  137. size_t len = 0;
  138. len = get(val, enc.idx) ? 3 : SIZE_MAX;
  139. if (jose_b64_dec_buf(enc.enc, 4, dec, sizeof(dec)) != len) {
  140. fprintf(stderr, "{%hu,%hu,%hu,%hu}\"%c%c%c%c\" != %zu\n",
  141. i, j, k, l, enc.enc[0], enc.enc[1], enc.enc[2], enc.enc[3], len);
  142. assert(false);
  143. }
  144. }
  145. }
  146. }
  147. }
  148. free(val);
  149. #endif
  150. return 0;
  151. }