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. 856083Skris * 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). 1556083Skris * 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. 2256083Skris * 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 :-). 3756083Skris * 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)" 4056083Skris * 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. 5256083Skris * 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 59279264Sdelphij#include "constant_time_locl.h" 60279264Sdelphij 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, 68109998Smarkm const unsigned char *from, int flen) 6956083Skris { 7056083Skris int j; 7156083Skris unsigned char *p; 7256083Skris 73109998Smarkm if (flen > (tlen-RSA_PKCS1_PADDING_SIZE)) 7456083Skris { 7556083Skris RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 7656083Skris return(0); 7756083Skris } 7856083Skris 7956083Skris p=(unsigned char *)to; 8056083Skris 8156083Skris *(p++)=0; 8256083Skris *(p++)=1; /* Private Key BT (Block Type) */ 8356083Skris 8459191Skris /* pad out with 0xff data */ 8556083Skris j=tlen-3-flen; 8656083Skris memset(p,0xff,j); 8756083Skris p+=j; 8856083Skris *(p++)='\0'; 8956083Skris memcpy(p,from,(unsigned int)flen); 9056083Skris return(1); 9156083Skris } 9256083Skris 9356083Skrisint RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, 94109998Smarkm const unsigned char *from, int flen, int num) 9556083Skris { 9656083Skris int i,j; 97109998Smarkm const unsigned char *p; 9856083Skris 9956083Skris p=from; 10056083Skris if ((num != (flen+1)) || (*(p++) != 01)) 10156083Skris { 10256083Skris RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01); 10356083Skris return(-1); 10456083Skris } 10556083Skris 10656083Skris /* scan over padding data */ 10756083Skris j=flen-1; /* one for type. */ 10856083Skris for (i=0; i<j; i++) 10956083Skris { 11056083Skris if (*p != 0xff) /* should decrypt to 0xff */ 11156083Skris { 11256083Skris if (*p == 0) 11356083Skris { p++; break; } 11456083Skris else { 11556083Skris RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_FIXED_HEADER_DECRYPT); 11656083Skris return(-1); 11756083Skris } 11856083Skris } 11956083Skris p++; 12056083Skris } 12156083Skris 12256083Skris if (i == j) 12356083Skris { 12456083Skris RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_NULL_BEFORE_BLOCK_MISSING); 12556083Skris return(-1); 12656083Skris } 12756083Skris 12856083Skris if (i < 8) 12956083Skris { 13056083Skris RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_PAD_BYTE_COUNT); 13156083Skris return(-1); 13256083Skris } 13356083Skris i++; /* Skip over the '\0' */ 13456083Skris j-=i; 13559191Skris if (j > tlen) 13659191Skris { 13759191Skris RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE); 13859191Skris return(-1); 13959191Skris } 14056083Skris memcpy(to,p,(unsigned int)j); 14156083Skris 14256083Skris return(j); 14356083Skris } 14456083Skris 14556083Skrisint RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, 146109998Smarkm const unsigned char *from, int flen) 14756083Skris { 14856083Skris int i,j; 14956083Skris unsigned char *p; 15056083Skris 15156083Skris if (flen > (tlen-11)) 15256083Skris { 15356083Skris RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 15456083Skris return(0); 15556083Skris } 15656083Skris 15756083Skris p=(unsigned char *)to; 15856083Skris 15956083Skris *(p++)=0; 16056083Skris *(p++)=2; /* Public Key BT (Block Type) */ 16156083Skris 16256083Skris /* pad out with non-zero random data */ 16356083Skris j=tlen-3-flen; 16456083Skris 16559191Skris if (RAND_bytes(p,j) <= 0) 16659191Skris return(0); 16756083Skris for (i=0; i<j; i++) 16856083Skris { 16956083Skris if (*p == '\0') 17056083Skris do { 17159191Skris if (RAND_bytes(p,1) <= 0) 17259191Skris return(0); 17356083Skris } while (*p == '\0'); 17456083Skris p++; 17556083Skris } 17656083Skris 17756083Skris *(p++)='\0'; 17856083Skris 17956083Skris memcpy(p,from,(unsigned int)flen); 18056083Skris return(1); 18156083Skris } 18256083Skris 18356083Skrisint RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, 184109998Smarkm const unsigned char *from, int flen, int num) 18556083Skris { 186279264Sdelphij int i; 187279264Sdelphij /* |em| is the encoded message, zero-padded to exactly |num| bytes */ 188279264Sdelphij unsigned char *em = NULL; 189279264Sdelphij unsigned int good, found_zero_byte; 190279264Sdelphij int zero_index = 0, msg_index, mlen = -1; 19156083Skris 192279264Sdelphij if (tlen < 0 || flen < 0) 193279264Sdelphij return -1; 194279264Sdelphij 195279264Sdelphij /* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography 196279264Sdelphij * Standard", section 7.2.2. */ 197279264Sdelphij 198279264Sdelphij if (flen > num) 199279264Sdelphij goto err; 200279264Sdelphij 201279264Sdelphij if (num < 11) 202279264Sdelphij goto err; 203279264Sdelphij 204279264Sdelphij em = OPENSSL_malloc(num); 205279264Sdelphij if (em == NULL) 20656083Skris { 207279264Sdelphij RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); 208279264Sdelphij return -1; 20956083Skris } 210279264Sdelphij memset(em, 0, num); 211279264Sdelphij /* 212279264Sdelphij * Always do this zero-padding copy (even when num == flen) to avoid 213279264Sdelphij * leaking that information. The copy still leaks some side-channel 214279264Sdelphij * information, but it's impossible to have a fixed memory access 215279264Sdelphij * pattern since we can't read out of the bounds of |from|. 216279264Sdelphij * 217279264Sdelphij * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. 218279264Sdelphij */ 219279264Sdelphij memcpy(em + num - flen, from, flen); 22056083Skris 221279264Sdelphij good = constant_time_is_zero(em[0]); 222279264Sdelphij good &= constant_time_eq(em[1], 2); 22356083Skris 224279264Sdelphij found_zero_byte = 0; 225279264Sdelphij for (i = 2; i < num; i++) 22656083Skris { 227279264Sdelphij unsigned int equals0 = constant_time_is_zero(em[i]); 228279264Sdelphij zero_index = constant_time_select_int(~found_zero_byte & equals0, i, zero_index); 229279264Sdelphij found_zero_byte |= equals0; 23056083Skris } 23156083Skris 232279264Sdelphij /* 233279264Sdelphij * PS must be at least 8 bytes long, and it starts two bytes into |em|. 234279264Sdelphij * If we never found a 0-byte, then |zero_index| is 0 and the check 235279264Sdelphij * also fails. 236279264Sdelphij */ 237279264Sdelphij good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); 238279264Sdelphij 239279264Sdelphij /* Skip the zero byte. This is incorrect if we never found a zero-byte 240279264Sdelphij * but in this case we also do not copy the message out. */ 241279264Sdelphij msg_index = zero_index + 1; 242279264Sdelphij mlen = num - msg_index; 243279264Sdelphij 244279264Sdelphij /* For good measure, do this check in constant time as well; it could 245279264Sdelphij * leak something if |tlen| was assuming valid padding. */ 246279264Sdelphij good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); 247279264Sdelphij 248279264Sdelphij /* 249279264Sdelphij * We can't continue in constant-time because we need to copy the result 250279264Sdelphij * and we cannot fake its length. This unavoidably leaks timing 251279264Sdelphij * information at the API boundary. 252279264Sdelphij * TODO(emilia): this could be addressed at the call site, 253279264Sdelphij * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. 254279264Sdelphij */ 255279264Sdelphij if (!good) 25656083Skris { 257279264Sdelphij mlen = -1; 258279264Sdelphij goto err; 25956083Skris } 26056083Skris 261279264Sdelphij memcpy(to, em + msg_index, mlen); 262279264Sdelphij 263279264Sdelphijerr: 264279264Sdelphij if (em != NULL) 265279264Sdelphij OPENSSL_free(em); 266279264Sdelphij if (mlen == -1) 267279264Sdelphij RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR); 268279264Sdelphij return mlen; 26956083Skris } 270