001-CVE-2017-13099.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. From fd455d5a5e9fef24c208e7ac7d3a4bc58834cbf1 Mon Sep 17 00:00:00 2001
  2. From: David Garske <david@wolfssl.com>
  3. Date: Tue, 14 Nov 2017 14:05:50 -0800
  4. Subject: [PATCH] Fix for handling of static RSA PKCS formatting failures so
  5. they are indistinguishable from from correctly formatted RSA blocks (per
  6. RFC5246 section 7.4.7.1). Adjusted the static RSA preMasterSecret RNG
  7. creation for consistency in client case. Removed obsolete
  8. `PMS_VERSION_ERROR`.
  9. ---
  10. src/internal.c | 70 +++++++++++++++++++++++++++++++++++++++++++++--------
  11. wolfssl/error-ssl.h | 2 +-
  12. 2 files changed, 61 insertions(+), 11 deletions(-)
  13. --- a/src/internal.c
  14. +++ b/src/internal.c
  15. @@ -14190,9 +14190,6 @@ const char* wolfSSL_ERR_reason_error_str
  16. case NOT_READY_ERROR :
  17. return "handshake layer not ready yet, complete first";
  18. - case PMS_VERSION_ERROR :
  19. - return "premaster secret version mismatch error";
  20. -
  21. case VERSION_ERROR :
  22. return "record layer version error";
  23. @@ -18758,8 +18755,10 @@ int SendClientKeyExchange(WOLFSSL* ssl)
  24. #ifndef NO_RSA
  25. case rsa_kea:
  26. {
  27. + /* build PreMasterSecret with RNG data */
  28. ret = wc_RNG_GenerateBlock(ssl->rng,
  29. - ssl->arrays->preMasterSecret, SECRET_LEN);
  30. + &ssl->arrays->preMasterSecret[VERSION_SZ],
  31. + SECRET_LEN - VERSION_SZ);
  32. if (ret != 0) {
  33. goto exit_scke;
  34. }
  35. @@ -23545,6 +23544,9 @@ static int DoSessionTicket(WOLFSSL* ssl,
  36. word32 idx;
  37. word32 begin;
  38. word32 sigSz;
  39. + #ifndef NO_RSA
  40. + int lastErr;
  41. + #endif
  42. } DckeArgs;
  43. static void FreeDckeArgs(WOLFSSL* ssl, void* pArgs)
  44. @@ -23770,6 +23772,14 @@ static int DoSessionTicket(WOLFSSL* ssl,
  45. ERROR_OUT(BUFFER_ERROR, exit_dcke);
  46. }
  47. + /* pre-load PreMasterSecret with RNG data */
  48. + ret = wc_RNG_GenerateBlock(ssl->rng,
  49. + &ssl->arrays->preMasterSecret[VERSION_SZ],
  50. + SECRET_LEN - VERSION_SZ);
  51. + if (ret != 0) {
  52. + goto exit_dcke;
  53. + }
  54. +
  55. args->output = NULL;
  56. break;
  57. } /* rsa_kea */
  58. @@ -24234,6 +24244,20 @@ static int DoSessionTicket(WOLFSSL* ssl,
  59. NULL, 0, NULL
  60. #endif
  61. );
  62. +
  63. + /* Errors that can occur here that should be
  64. + * indistinguishable:
  65. + * RSA_BUFFER_E, RSA_PAD_E and RSA_PRIVATE_ERROR
  66. + */
  67. + if (ret < 0 && ret != BAD_FUNC_ARG) {
  68. + #ifdef WOLFSSL_ASYNC_CRYPT
  69. + if (ret == WC_PENDING_E)
  70. + goto exit_dcke;
  71. + #endif
  72. + /* store error code for handling below */
  73. + args->lastErr = ret;
  74. + ret = 0;
  75. + }
  76. break;
  77. } /* rsa_kea */
  78. #endif /* !NO_RSA */
  79. @@ -24380,16 +24404,42 @@ static int DoSessionTicket(WOLFSSL* ssl,
  80. /* Add the signature length to idx */
  81. args->idx += args->length;
  82. - if (args->sigSz == SECRET_LEN && args->output != NULL) {
  83. - XMEMCPY(ssl->arrays->preMasterSecret, args->output, SECRET_LEN);
  84. - if (ssl->arrays->preMasterSecret[0] != ssl->chVersion.major ||
  85. - ssl->arrays->preMasterSecret[1] != ssl->chVersion.minor) {
  86. - ERROR_OUT(PMS_VERSION_ERROR, exit_dcke);
  87. + #ifdef DEBUG_WOLFSSL
  88. + /* check version (debug warning message only) */
  89. + if (args->output != NULL) {
  90. + if (args->output[0] != ssl->chVersion.major ||
  91. + args->output[1] != ssl->chVersion.minor) {
  92. + WOLFSSL_MSG("preMasterSecret version mismatch");
  93. }
  94. }
  95. + #endif
  96. +
  97. + /* RFC5246 7.4.7.1:
  98. + * Treat incorrectly formatted message blocks and/or
  99. + * mismatched version numbers in a manner
  100. + * indistinguishable from correctly formatted RSA blocks
  101. + */
  102. +
  103. + ret = args->lastErr;
  104. + args->lastErr = 0; /* reset */
  105. +
  106. + /* build PreMasterSecret */
  107. + ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
  108. + ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
  109. + if (ret == 0 && args->sigSz == SECRET_LEN &&
  110. + args->output != NULL) {
  111. + XMEMCPY(&ssl->arrays->preMasterSecret[VERSION_SZ],
  112. + &args->output[VERSION_SZ],
  113. + SECRET_LEN - VERSION_SZ);
  114. + }
  115. else {
  116. - ERROR_OUT(RSA_PRIVATE_ERROR, exit_dcke);
  117. + /* preMasterSecret has RNG and version set */
  118. + /* return proper length and ignore error */
  119. + /* error will be caught as decryption error */
  120. + args->sigSz = SECRET_LEN;
  121. + ret = 0;
  122. }
  123. +
  124. break;
  125. } /* rsa_kea */
  126. #endif /* !NO_RSA */
  127. --- a/wolfssl/error-ssl.h
  128. +++ b/wolfssl/error-ssl.h
  129. @@ -57,7 +57,7 @@ enum wolfSSL_ErrorCodes {
  130. DOMAIN_NAME_MISMATCH = -322, /* peer subject name mismatch */
  131. WANT_READ = -323, /* want read, call again */
  132. NOT_READY_ERROR = -324, /* handshake layer not ready */
  133. - PMS_VERSION_ERROR = -325, /* pre m secret version error */
  134. +
  135. VERSION_ERROR = -326, /* record layer version error */
  136. WANT_WRITE = -327, /* want write, call again */
  137. BUFFER_ERROR = -328, /* malformed buffer input */