xref: /openssl/crypto/rsa/rsa_x931.c (revision 7ed6de99)
1 /*
2  * Copyright 2005-2024 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * RSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <stdio.h>
17 #include "internal/cryptlib.h"
18 #include <openssl/bn.h>
19 #include <openssl/rsa.h>
20 #include <openssl/objects.h>
21 
22 /*
23  * X9.31 Embeds the hash inside the following data structure
24  *
25  * header (4 bits = 0x6)
26  * padding (consisting of zero or more 4 bit values of a sequence of 0xB,
27  *          ending with the terminator 0xA)
28  * hash(Msg) hash of a message (the output size is related to the hash function)
29  * trailer (consists of 2 bytes)
30  *         The 1st byte is related to a part number for a hash algorithm
31  *         (See RSA_X931_hash_id()), followed by the fixed value 0xCC
32  *
33  * The RSA modulus size n (which for X9.31 is 1024 + 256*s) is the size of the data
34  * structure, which determines the padding size.
35  * i.e. len(padding) = n - len(header) - len(hash) - len(trailer)
36  *
37  * Params:
38  *     to The output buffer to write the data structure to.
39  *     tolen The size of 'to' in bytes (it is the size of the n)
40  *     from The input hash followed by the 1st byte of the trailer.
41  *     flen The size of the input hash + 1 (trailer byte)
42  */
RSA_padding_add_X931(unsigned char * to,int tlen,const unsigned char * from,int flen)43 int RSA_padding_add_X931(unsigned char *to, int tlen,
44                          const unsigned char *from, int flen)
45 {
46     int j;
47     unsigned char *p;
48 
49     /*
50      * We need at least 1 byte for header + padding (0x6A)
51      * And 2 trailer bytes (but we subtract 1 since flen includes 1 trailer byte)
52      */
53     j = tlen - flen - 2;
54 
55     if (j < 0) {
56         ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
57         return -1;
58     }
59 
60     p = (unsigned char *)to;
61 
62     /* If no padding start and end nibbles are in one byte */
63     if (j == 0) {
64         *p++ = 0x6A;
65     } else {
66         *p++ = 0x6B;
67         if (j > 1) {
68             memset(p, 0xBB, j - 1);
69             p += j - 1;
70         }
71         *p++ = 0xBA;
72     }
73     memcpy(p, from, (unsigned int)flen);
74     p += flen;
75     *p = 0xCC;
76     return 1;
77 }
78 
RSA_padding_check_X931(unsigned char * to,int tlen,const unsigned char * from,int flen,int num)79 int RSA_padding_check_X931(unsigned char *to, int tlen,
80                            const unsigned char *from, int flen, int num)
81 {
82     int i = 0, j;
83     const unsigned char *p;
84 
85     p = from;
86     if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) {
87         ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_HEADER);
88         return -1;
89     }
90 
91     if (*p++ == 0x6B) {
92         j = flen - 3;
93         for (i = 0; i < j; i++) {
94             unsigned char c = *p++;
95             if (c == 0xBA)
96                 break;
97             if (c != 0xBB) {
98                 ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING);
99                 return -1;
100             }
101         }
102 
103         j -= i;
104 
105         if (i == 0) {
106             ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PADDING);
107             return -1;
108         }
109 
110     } else {
111         j = flen - 2;
112     }
113 
114     if (p[j] != 0xCC) {
115         ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_TRAILER);
116         return -1;
117     }
118 
119     memcpy(to, p, (unsigned int)j);
120 
121     return j;
122 }
123 
124 /*
125  * Translate between X9.31 hash ids and NIDs
126  * The returned values relate to ISO/IEC 10118 part numbers which consist of
127  * a hash algorithm and hash number. The returned values are used as the
128  * first byte of the 'trailer'.
129  */
130 
RSA_X931_hash_id(int nid)131 int RSA_X931_hash_id(int nid)
132 {
133     switch (nid) {
134     case NID_sha1:
135         return 0x33;
136 
137     case NID_sha256:
138         return 0x34;
139 
140     case NID_sha384:
141         return 0x36;
142 
143     case NID_sha512:
144         return 0x35;
145 
146     }
147     return -1;
148 }
149