aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/openssl/crypto/rsa/rsa_x931.c
blob: f34fadb34355f944ddd9b12a5de166bf442d4664 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* 
 * Copyright 2005-2017 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/objects.h> 
 
int RSA_padding_add_X931(unsigned char *to, int tlen, 
                         const unsigned char *from, int flen) 
{ 
    int j; 
    unsigned char *p; 
 
    /* 
     * Absolute minimum amount of padding is 1 header nibble, 1 padding 
     * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. 
     */ 
 
    j = tlen - flen - 2; 
 
    if (j < 0) { 
        RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); 
        return -1; 
    } 
 
    p = (unsigned char *)to; 
 
    /* If no padding start and end nibbles are in one byte */ 
    if (j == 0) { 
        *p++ = 0x6A; 
    } else { 
        *p++ = 0x6B; 
        if (j > 1) { 
            memset(p, 0xBB, j - 1); 
            p += j - 1; 
        } 
        *p++ = 0xBA; 
    } 
    memcpy(p, from, (unsigned int)flen); 
    p += flen; 
    *p = 0xCC; 
    return 1; 
} 
 
int RSA_padding_check_X931(unsigned char *to, int tlen, 
                           const unsigned char *from, int flen, int num) 
{ 
    int i = 0, j; 
    const unsigned char *p; 
 
    p = from; 
    if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { 
        RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); 
        return -1; 
    } 
 
    if (*p++ == 0x6B) { 
        j = flen - 3; 
        for (i = 0; i < j; i++) { 
            unsigned char c = *p++; 
            if (c == 0xBA) 
                break; 
            if (c != 0xBB) { 
                RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); 
                return -1; 
            } 
        } 
 
        j -= i; 
 
        if (i == 0) { 
            RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); 
            return -1; 
        } 
 
    } else { 
        j = flen - 2; 
    } 
 
    if (p[j] != 0xCC) { 
        RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); 
        return -1; 
    } 
 
    memcpy(to, p, (unsigned int)j); 
 
    return j; 
} 
 
/* Translate between X931 hash ids and NIDs */ 
 
int RSA_X931_hash_id(int nid) 
{ 
    switch (nid) { 
    case NID_sha1: 
        return 0x33; 
 
    case NID_sha256: 
        return 0x34; 
 
    case NID_sha384: 
        return 0x36; 
 
    case NID_sha512: 
        return 0x35; 
 
    } 
    return -1; 
}