156083Skris/* crypto/rsa/rsa_pk1.c */ 256083Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 356083Skris * All rights reserved. 456083Skris * 556083Skris * This package is an SSL implementation written 656083Skris * by Eric Young (eay@cryptsoft.com). 756083Skris * The implementation was written so as to conform with Netscapes SSL. 8280304Sjkim * 956083Skris * This library is free for commercial and non-commercial use as long as 1056083Skris * the following conditions are aheared to. The following conditions 1156083Skris * apply to all code found in this distribution, be it the RC4, RSA, 1256083Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1356083Skris * included with this distribution is covered by the same copyright terms 1456083Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280304Sjkim * 1656083Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1756083Skris * the code are not to be removed. 1856083Skris * If this package is used in a product, Eric Young should be given attribution 1956083Skris * as the author of the parts of the library used. 2056083Skris * This can be in the form of a textual message at program startup or 2156083Skris * in documentation (online or textual) provided with the package. 22280304Sjkim * 2356083Skris * Redistribution and use in source and binary forms, with or without 2456083Skris * modification, are permitted provided that the following conditions 2556083Skris * are met: 2656083Skris * 1. Redistributions of source code must retain the copyright 2756083Skris * notice, this list of conditions and the following disclaimer. 2856083Skris * 2. Redistributions in binary form must reproduce the above copyright 2956083Skris * notice, this list of conditions and the following disclaimer in the 3056083Skris * documentation and/or other materials provided with the distribution. 3156083Skris * 3. All advertising materials mentioning features or use of this software 3256083Skris * must display the following acknowledgement: 3356083Skris * "This product includes cryptographic software written by 3456083Skris * Eric Young (eay@cryptsoft.com)" 3556083Skris * The word 'cryptographic' can be left out if the rouines from the library 3656083Skris * being used are not cryptographic related :-). 37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3856083Skris * the apps directory (application code) you must include an acknowledgement: 3956083Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280304Sjkim * 4156083Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4256083Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4356083Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4456083Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4556083Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4656083Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4756083Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4856083Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4956083Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5056083Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5156083Skris * SUCH DAMAGE. 52280304Sjkim * 5356083Skris * The licence and distribution terms for any publically available version or 5456083Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5556083Skris * copied and put under another distribution licence 5656083Skris * [including the GNU Public Licence.] 5756083Skris */ 5856083Skris 59273149Sjkim#include "constant_time_locl.h" 60273149Sjkim 6156083Skris#include <stdio.h> 6256083Skris#include "cryptlib.h" 6356083Skris#include <openssl/bn.h> 6456083Skris#include <openssl/rsa.h> 6556083Skris#include <openssl/rand.h> 6656083Skris 6756083Skrisint RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, 68280304Sjkim const unsigned char *from, int flen) 69280304Sjkim{ 70280304Sjkim int j; 71280304Sjkim unsigned char *p; 7256083Skris 73280304Sjkim if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { 74280304Sjkim RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, 75280304Sjkim RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 76280304Sjkim return (0); 77280304Sjkim } 7856083Skris 79280304Sjkim p = (unsigned char *)to; 8056083Skris 81280304Sjkim *(p++) = 0; 82280304Sjkim *(p++) = 1; /* Private Key BT (Block Type) */ 8356083Skris 84280304Sjkim /* pad out with 0xff data */ 85280304Sjkim j = tlen - 3 - flen; 86280304Sjkim memset(p, 0xff, j); 87280304Sjkim p += j; 88280304Sjkim *(p++) = '\0'; 89280304Sjkim memcpy(p, from, (unsigned int)flen); 90280304Sjkim return (1); 91280304Sjkim} 92280304Sjkim 9356083Skrisint RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, 94280304Sjkim const unsigned char *from, int flen, 95280304Sjkim int num) 96280304Sjkim{ 97280304Sjkim int i, j; 98280304Sjkim const unsigned char *p; 9956083Skris 100280304Sjkim p = from; 101280304Sjkim if ((num != (flen + 1)) || (*(p++) != 01)) { 102280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 103280304Sjkim RSA_R_BLOCK_TYPE_IS_NOT_01); 104280304Sjkim return (-1); 105280304Sjkim } 10656083Skris 107280304Sjkim /* scan over padding data */ 108280304Sjkim j = flen - 1; /* one for type. */ 109280304Sjkim for (i = 0; i < j; i++) { 110280304Sjkim if (*p != 0xff) { /* should decrypt to 0xff */ 111280304Sjkim if (*p == 0) { 112280304Sjkim p++; 113280304Sjkim break; 114280304Sjkim } else { 115280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 116280304Sjkim RSA_R_BAD_FIXED_HEADER_DECRYPT); 117280304Sjkim return (-1); 118280304Sjkim } 119280304Sjkim } 120280304Sjkim p++; 121280304Sjkim } 12256083Skris 123280304Sjkim if (i == j) { 124280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 125280304Sjkim RSA_R_NULL_BEFORE_BLOCK_MISSING); 126280304Sjkim return (-1); 127280304Sjkim } 12856083Skris 129280304Sjkim if (i < 8) { 130280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, 131280304Sjkim RSA_R_BAD_PAD_BYTE_COUNT); 132280304Sjkim return (-1); 133280304Sjkim } 134280304Sjkim i++; /* Skip over the '\0' */ 135280304Sjkim j -= i; 136280304Sjkim if (j > tlen) { 137280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); 138280304Sjkim return (-1); 139280304Sjkim } 140280304Sjkim memcpy(to, p, (unsigned int)j); 14156083Skris 142280304Sjkim return (j); 143280304Sjkim} 14456083Skris 14556083Skrisint RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, 146280304Sjkim const unsigned char *from, int flen) 147280304Sjkim{ 148280304Sjkim int i, j; 149280304Sjkim unsigned char *p; 15056083Skris 151280304Sjkim if (flen > (tlen - 11)) { 152280304Sjkim RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, 153280304Sjkim RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 154280304Sjkim return (0); 155280304Sjkim } 15656083Skris 157280304Sjkim p = (unsigned char *)to; 15856083Skris 159280304Sjkim *(p++) = 0; 160280304Sjkim *(p++) = 2; /* Public Key BT (Block Type) */ 16156083Skris 162280304Sjkim /* pad out with non-zero random data */ 163280304Sjkim j = tlen - 3 - flen; 16456083Skris 165280304Sjkim if (RAND_bytes(p, j) <= 0) 166280304Sjkim return (0); 167280304Sjkim for (i = 0; i < j; i++) { 168280304Sjkim if (*p == '\0') 169280304Sjkim do { 170280304Sjkim if (RAND_bytes(p, 1) <= 0) 171280304Sjkim return (0); 172280304Sjkim } while (*p == '\0'); 173280304Sjkim p++; 174280304Sjkim } 17556083Skris 176280304Sjkim *(p++) = '\0'; 177280304Sjkim 178280304Sjkim memcpy(p, from, (unsigned int)flen); 179280304Sjkim return (1); 180280304Sjkim} 181280304Sjkim 18256083Skrisint RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, 183280304Sjkim const unsigned char *from, int flen, 184280304Sjkim int num) 185280304Sjkim{ 186280304Sjkim int i; 187280304Sjkim /* |em| is the encoded message, zero-padded to exactly |num| bytes */ 188280304Sjkim unsigned char *em = NULL; 189280304Sjkim unsigned int good, found_zero_byte; 190280304Sjkim int zero_index = 0, msg_index, mlen = -1; 19156083Skris 192280304Sjkim if (tlen < 0 || flen < 0) 193280304Sjkim return -1; 194273149Sjkim 195280304Sjkim /* 196280304Sjkim * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", 197280304Sjkim * section 7.2.2. 198280304Sjkim */ 199273149Sjkim 200280304Sjkim if (flen > num) 201280304Sjkim goto err; 202273149Sjkim 203280304Sjkim if (num < 11) 204280304Sjkim goto err; 205273149Sjkim 206280304Sjkim em = OPENSSL_malloc(num); 207280304Sjkim if (em == NULL) { 208280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); 209280304Sjkim return -1; 210280304Sjkim } 211280304Sjkim memset(em, 0, num); 212280304Sjkim /* 213280304Sjkim * Always do this zero-padding copy (even when num == flen) to avoid 214280304Sjkim * leaking that information. The copy still leaks some side-channel 215280304Sjkim * information, but it's impossible to have a fixed memory access 216280304Sjkim * pattern since we can't read out of the bounds of |from|. 217280304Sjkim * 218280304Sjkim * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. 219280304Sjkim */ 220280304Sjkim memcpy(em + num - flen, from, flen); 22156083Skris 222280304Sjkim good = constant_time_is_zero(em[0]); 223280304Sjkim good &= constant_time_eq(em[1], 2); 22456083Skris 225280304Sjkim found_zero_byte = 0; 226280304Sjkim for (i = 2; i < num; i++) { 227280304Sjkim unsigned int equals0 = constant_time_is_zero(em[i]); 228280304Sjkim zero_index = 229280304Sjkim constant_time_select_int(~found_zero_byte & equals0, i, 230280304Sjkim zero_index); 231280304Sjkim found_zero_byte |= equals0; 232280304Sjkim } 23356083Skris 234280304Sjkim /* 235280304Sjkim * PS must be at least 8 bytes long, and it starts two bytes into |em|. 236280304Sjkim * If we never found a 0-byte, then |zero_index| is 0 and the check 237280304Sjkim * also fails. 238280304Sjkim */ 239280304Sjkim good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); 240273149Sjkim 241280304Sjkim /* 242280304Sjkim * Skip the zero byte. This is incorrect if we never found a zero-byte 243280304Sjkim * but in this case we also do not copy the message out. 244280304Sjkim */ 245280304Sjkim msg_index = zero_index + 1; 246280304Sjkim mlen = num - msg_index; 247273149Sjkim 248280304Sjkim /* 249280304Sjkim * For good measure, do this check in constant time as well; it could 250280304Sjkim * leak something if |tlen| was assuming valid padding. 251280304Sjkim */ 252280304Sjkim good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); 253273149Sjkim 254280304Sjkim /* 255280304Sjkim * We can't continue in constant-time because we need to copy the result 256280304Sjkim * and we cannot fake its length. This unavoidably leaks timing 257280304Sjkim * information at the API boundary. 258280304Sjkim * TODO(emilia): this could be addressed at the call site, 259280304Sjkim * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. 260280304Sjkim */ 261280304Sjkim if (!good) { 262280304Sjkim mlen = -1; 263280304Sjkim goto err; 264280304Sjkim } 26556083Skris 266280304Sjkim memcpy(to, em + msg_index, mlen); 267273149Sjkim 268280304Sjkim err: 269280304Sjkim if (em != NULL) 270280304Sjkim OPENSSL_free(em); 271280304Sjkim if (mlen == -1) 272280304Sjkim RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, 273280304Sjkim RSA_R_PKCS_DECODING_ERROR); 274280304Sjkim return mlen; 275280304Sjkim} 276