1
2
3
4
5 package rsa
6
7
8
9 import (
10 "bytes"
11 "crypto/internal/fips140"
12 "errors"
13 )
14
15
16
17
18
19
20
21
22
23
24
25 var hashPrefixes = map[string][]byte{
26 "MD5": {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
27 "SHA-1": {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
28 "SHA-224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
29 "SHA-256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
30 "SHA-384": {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
31 "SHA-512": {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
32 "SHA-512/224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x05, 0x00, 0x04, 0x1C},
33 "SHA-512/256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20},
34 "SHA3-224": {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1C},
35 "SHA3-256": {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20},
36 "SHA3-384": {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30},
37 "SHA3-512": {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0a, 0x05, 0x00, 0x04, 0x40},
38 "MD5+SHA1": {},
39 "RIPEMD-160": {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
40 }
41
42
43
44
45
46 func SignPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
47 fipsSelfTest()
48 fips140.RecordApproved()
49 checkApprovedHashName(hash)
50
51 return signPKCS1v15(priv, hash, hashed)
52 }
53
54 func signPKCS1v15(priv *PrivateKey, hash string, hashed []byte) ([]byte, error) {
55 em, err := pkcs1v15ConstructEM(&priv.pub, hash, hashed)
56 if err != nil {
57 return nil, err
58 }
59
60 return decrypt(priv, em, withCheck)
61 }
62
63 func pkcs1v15ConstructEM(pub *PublicKey, hash string, hashed []byte) ([]byte, error) {
64
65 var prefix []byte
66 if hash != "" {
67 var ok bool
68 prefix, ok = hashPrefixes[hash]
69 if !ok {
70 return nil, errors.New("crypto/rsa: unsupported hash function")
71 }
72 }
73
74
75 k := pub.Size()
76 if k < len(prefix)+len(hashed)+2+8+1 {
77 return nil, ErrMessageTooLong
78 }
79 em := make([]byte, k)
80 em[1] = 1
81 for i := 2; i < k-len(prefix)-len(hashed)-1; i++ {
82 em[i] = 0xff
83 }
84 copy(em[k-len(prefix)-len(hashed):], prefix)
85 copy(em[k-len(hashed):], hashed)
86 return em, nil
87 }
88
89
90
91
92
93 func VerifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) error {
94 fipsSelfTest()
95 fips140.RecordApproved()
96 checkApprovedHashName(hash)
97
98 return verifyPKCS1v15(pub, hash, hashed, sig)
99 }
100
101 func verifyPKCS1v15(pub *PublicKey, hash string, hashed []byte, sig []byte) error {
102 if fipsApproved, err := checkPublicKey(pub); err != nil {
103 return err
104 } else if !fipsApproved {
105 fips140.RecordNonApproved()
106 }
107
108
109
110
111 if pub.Size() != len(sig) {
112 return ErrVerification
113 }
114
115 em, err := encrypt(pub, sig)
116 if err != nil {
117 return ErrVerification
118 }
119
120 expected, err := pkcs1v15ConstructEM(pub, hash, hashed)
121 if err != nil {
122 return ErrVerification
123 }
124 if !bytes.Equal(em, expected) {
125 return ErrVerification
126 }
127
128 return nil
129 }
130
131 func checkApprovedHashName(hash string) {
132 switch hash {
133 case "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA-512/224", "SHA-512/256",
134 "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512":
135 default:
136 fips140.RecordNonApproved()
137 }
138 }
139
View as plain text