1 /* 2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining 5 * a copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #include "inner.h" 26 27 /* see inner.h */ 28 uint32_t 29 br_rsa_pkcs1_sig_pad(const unsigned char *hash_oid, 30 const unsigned char *hash, size_t hash_len, 31 uint32_t n_bitlen, unsigned char *x) 32 { 33 size_t u, x3, xlen; 34 35 /* 36 * Padded hash value has format: 37 * 00 01 FF .. FF 00 30 x1 30 x2 06 x3 OID 05 00 04 x4 HASH 38 * 39 * with the following rules: 40 * 41 * -- Total length is equal to the modulus length (unsigned 42 * encoding). 43 * 44 * -- There must be at least eight bytes of value 0xFF. 45 * 46 * -- x4 is equal to the hash length (hash_len). 47 * 48 * -- x3 is equal to the encoded OID value length (hash_oid[0]). 49 * 50 * -- x2 = x3 + 4. 51 * 52 * -- x1 = x2 + x4 + 4 = x3 + x4 + 8. 53 * 54 * Note: the "05 00" is optional (signatures with and without 55 * that sequence exist in practice), but notes in PKCS#1 seem to 56 * indicate that the presence of that sequence (specifically, 57 * an ASN.1 NULL value for the hash parameters) may be slightly 58 * more "standard" than the opposite. 59 */ 60 xlen = (n_bitlen + 7) >> 3; 61 62 if (hash_oid == NULL) { 63 if (xlen < hash_len + 11) { 64 return 0; 65 } 66 x[0] = 0x00; 67 x[1] = 0x01; 68 u = xlen - hash_len; 69 memset(x + 2, 0xFF, u - 3); 70 x[u - 1] = 0x00; 71 } else { 72 x3 = hash_oid[0]; 73 74 /* 75 * Check that there is enough room for all the elements, 76 * including at least eight bytes of value 0xFF. 77 */ 78 if (xlen < (x3 + hash_len + 21)) { 79 return 0; 80 } 81 x[0] = 0x00; 82 x[1] = 0x01; 83 u = xlen - x3 - hash_len - 11; 84 memset(x + 2, 0xFF, u - 2); 85 x[u] = 0x00; 86 x[u + 1] = 0x30; 87 x[u + 2] = x3 + hash_len + 8; 88 x[u + 3] = 0x30; 89 x[u + 4] = x3 + 4; 90 x[u + 5] = 0x06; 91 memcpy(x + u + 6, hash_oid, x3 + 1); 92 u += x3 + 7; 93 x[u ++] = 0x05; 94 x[u ++] = 0x00; 95 x[u ++] = 0x04; 96 x[u ++] = hash_len; 97 } 98 memcpy(x + u, hash, hash_len); 99 return 1; 100 } 101