| /* |
| * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. |
| * |
| * Licensed under the OpenSSL license (the "License"). You may not use |
| * this file except in compliance with the License. You can obtain a copy |
| * in the file LICENSE in the source distribution or at |
| * https://www.openssl.org/source/license.html |
| */ |
| |
| #include <stdio.h> |
| #include "internal/cryptlib.h" |
| #include <openssl/bn.h> |
| #include <openssl/rsa.h> |
| #include <openssl/rand.h> |
| |
| int RSA_padding_add_SSLv23(unsigned char *to, int tlen, |
| const unsigned char *from, int flen) |
| { |
| int i, j; |
| unsigned char *p; |
| |
| if (flen > (tlen - 11)) { |
| RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, |
| RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); |
| return (0); |
| } |
| |
| p = (unsigned char *)to; |
| |
| *(p++) = 0; |
| *(p++) = 2; /* Public Key BT (Block Type) */ |
| |
| /* pad out with non-zero random data */ |
| j = tlen - 3 - 8 - flen; |
| |
| if (RAND_bytes(p, j) <= 0) |
| return (0); |
| for (i = 0; i < j; i++) { |
| if (*p == '\0') |
| do { |
| if (RAND_bytes(p, 1) <= 0) |
| return (0); |
| } while (*p == '\0'); |
| p++; |
| } |
| |
| memset(p, 3, 8); |
| p += 8; |
| *(p++) = '\0'; |
| |
| memcpy(p, from, (unsigned int)flen); |
| return (1); |
| } |
| |
| int RSA_padding_check_SSLv23(unsigned char *to, int tlen, |
| const unsigned char *from, int flen, int num) |
| { |
| int i, j, k; |
| const unsigned char *p; |
| |
| p = from; |
| if (flen < 10) { |
| RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); |
| return (-1); |
| } |
| if ((num != (flen + 1)) || (*(p++) != 02)) { |
| RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); |
| return (-1); |
| } |
| |
| /* scan over padding data */ |
| j = flen - 1; /* one for type */ |
| for (i = 0; i < j; i++) |
| if (*(p++) == 0) |
| break; |
| |
| if ((i == j) || (i < 8)) { |
| RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, |
| RSA_R_NULL_BEFORE_BLOCK_MISSING); |
| return (-1); |
| } |
| for (k = -9; k < -1; k++) { |
| if (p[k] != 0x03) |
| break; |
| } |
| if (k == -1) { |
| RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK); |
| return (-1); |
| } |
| |
| i++; /* Skip over the '\0' */ |
| j -= i; |
| if (j > tlen) { |
| RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE); |
| return (-1); |
| } |
| memcpy(to, p, (unsigned int)j); |
| |
| return (j); |
| } |