2
0

x_long.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright 2000-2017 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 <stdio.h>
  10. #include "internal/cryptlib.h"
  11. #include <openssl/asn1t.h>
  12. #if OPENSSL_API_3
  13. NON_EMPTY_TRANSLATION_UNIT
  14. #else
  15. #define COPY_SIZE(a, b) (sizeof(a) < sizeof(b) ? sizeof(a) : sizeof(b))
  16. /*
  17. * Custom primitive type for long handling. This converts between an
  18. * ASN1_INTEGER and a long directly.
  19. */
  20. static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
  21. static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
  22. static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
  23. const ASN1_ITEM *it);
  24. static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
  25. int utype, char *free_cont, const ASN1_ITEM *it);
  26. static int long_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
  27. int indent, const ASN1_PCTX *pctx);
  28. static ASN1_PRIMITIVE_FUNCS long_pf = {
  29. NULL, 0,
  30. long_new,
  31. long_free,
  32. long_free, /* Clear should set to initial value */
  33. long_c2i,
  34. long_i2c,
  35. long_print
  36. };
  37. ASN1_ITEM_start(LONG)
  38. ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
  39. ASN1_ITEM_end(LONG)
  40. ASN1_ITEM_start(ZLONG)
  41. ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
  42. ASN1_ITEM_end(ZLONG)
  43. static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
  44. {
  45. memcpy(pval, &it->size, COPY_SIZE(*pval, it->size));
  46. return 1;
  47. }
  48. static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
  49. {
  50. memcpy(pval, &it->size, COPY_SIZE(*pval, it->size));
  51. }
  52. /*
  53. * Originally BN_num_bits_word was called to perform this operation, but
  54. * trouble is that there is no guarantee that sizeof(long) equals to
  55. * sizeof(BN_ULONG). BN_ULONG is a configurable type that can be as wide
  56. * as long, but also double or half...
  57. */
  58. static int num_bits_ulong(unsigned long value)
  59. {
  60. size_t i;
  61. unsigned long ret = 0;
  62. /*
  63. * It is argued that *on average* constant counter loop performs
  64. * not worse [if not better] than one with conditional break or
  65. * mask-n-table-lookup-style, because of branch misprediction
  66. * penalties.
  67. */
  68. for (i = 0; i < sizeof(value) * 8; i++) {
  69. ret += (value != 0);
  70. value >>= 1;
  71. }
  72. return (int)ret;
  73. }
  74. static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
  75. const ASN1_ITEM *it)
  76. {
  77. long ltmp;
  78. unsigned long utmp, sign;
  79. int clen, pad, i;
  80. memcpy(&ltmp, pval, COPY_SIZE(*pval, ltmp));
  81. if (ltmp == it->size)
  82. return -1;
  83. /*
  84. * Convert the long to positive: we subtract one if negative so we can
  85. * cleanly handle the padding if only the MSB of the leading octet is
  86. * set.
  87. */
  88. if (ltmp < 0) {
  89. sign = 0xff;
  90. utmp = 0 - (unsigned long)ltmp - 1;
  91. } else {
  92. sign = 0;
  93. utmp = ltmp;
  94. }
  95. clen = num_bits_ulong(utmp);
  96. /* If MSB of leading octet set we need to pad */
  97. if (!(clen & 0x7))
  98. pad = 1;
  99. else
  100. pad = 0;
  101. /* Convert number of bits to number of octets */
  102. clen = (clen + 7) >> 3;
  103. if (cont != NULL) {
  104. if (pad)
  105. *cont++ = (unsigned char)sign;
  106. for (i = clen - 1; i >= 0; i--) {
  107. cont[i] = (unsigned char)(utmp ^ sign);
  108. utmp >>= 8;
  109. }
  110. }
  111. return clen + pad;
  112. }
  113. static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
  114. int utype, char *free_cont, const ASN1_ITEM *it)
  115. {
  116. int i;
  117. long ltmp;
  118. unsigned long utmp = 0, sign = 0x100;
  119. if (len > 1) {
  120. /*
  121. * Check possible pad byte. Worst case, we're skipping past actual
  122. * content, but since that's only with 0x00 and 0xff and we set neg
  123. * accordingly, the result will be correct in the end anyway.
  124. */
  125. switch (cont[0]) {
  126. case 0xff:
  127. cont++;
  128. len--;
  129. sign = 0xff;
  130. break;
  131. case 0:
  132. cont++;
  133. len--;
  134. sign = 0;
  135. break;
  136. }
  137. }
  138. if (len > (int)sizeof(long)) {
  139. ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
  140. return 0;
  141. }
  142. if (sign == 0x100) {
  143. /* Is it negative? */
  144. if (len && (cont[0] & 0x80))
  145. sign = 0xff;
  146. else
  147. sign = 0;
  148. } else if (((sign ^ cont[0]) & 0x80) == 0) { /* same sign bit? */
  149. ASN1err(ASN1_F_LONG_C2I, ASN1_R_ILLEGAL_PADDING);
  150. return 0;
  151. }
  152. utmp = 0;
  153. for (i = 0; i < len; i++) {
  154. utmp <<= 8;
  155. utmp |= cont[i] ^ sign;
  156. }
  157. ltmp = (long)utmp;
  158. if (ltmp < 0) {
  159. ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
  160. return 0;
  161. }
  162. if (sign)
  163. ltmp = -ltmp - 1;
  164. if (ltmp == it->size) {
  165. ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
  166. return 0;
  167. }
  168. memcpy(pval, &ltmp, COPY_SIZE(*pval, ltmp));
  169. return 1;
  170. }
  171. static int long_print(BIO *out, const ASN1_VALUE **pval, const ASN1_ITEM *it,
  172. int indent, const ASN1_PCTX *pctx)
  173. {
  174. long l;
  175. memcpy(&l, pval, COPY_SIZE(*pval, l));
  176. return BIO_printf(out, "%ld\n", l);
  177. }
  178. #endif