File: types_cipher_suite_id.go

package info (click to toggle)
golang-github-bougou-go-ipmi 0.7.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,880 kB
  • sloc: makefile: 38
file content (182 lines) | stat: -rw-r--r-- 6,533 bytes parent folder | download | duplicates (2)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package ipmi

import "context"

// 22.15.2 Cipher Suite IDs
type CipherSuiteID uint8

const (
	CipherSuiteID0        CipherSuiteID = 0
	CipherSuiteID1        CipherSuiteID = 1
	CipherSuiteID2        CipherSuiteID = 2
	CipherSuiteID3        CipherSuiteID = 3
	CipherSuiteID4        CipherSuiteID = 4
	CipherSuiteID5        CipherSuiteID = 5
	CipherSuiteID6        CipherSuiteID = 6
	CipherSuiteID7        CipherSuiteID = 7
	CipherSuiteID8        CipherSuiteID = 8
	CipherSuiteID9        CipherSuiteID = 9
	CipherSuiteID10       CipherSuiteID = 10
	CipherSuiteID11       CipherSuiteID = 11
	CipherSuiteID12       CipherSuiteID = 12
	CipherSuiteID13       CipherSuiteID = 13
	CipherSuiteID14       CipherSuiteID = 14
	CipherSuiteID15       CipherSuiteID = 15
	CipherSuiteID16       CipherSuiteID = 16
	CipherSuiteID17       CipherSuiteID = 17
	CipherSuiteID18       CipherSuiteID = 18
	CipherSuiteID19       CipherSuiteID = 19
	CipherSuiteIDReserved CipherSuiteID = 0xff
)

const (
	StandardCipherSuite uint8 = 0xc0
	OEMCipherSuite      uint8 = 0xc1

	CipherAlgMask       uint8 = 0x3f // [5:0]=111111b
	CipherAlgTagBitMask uint8 = 0xc0 // [7:6]=11b

	CipherAlgTagBitAuthMask       uint8 = 0x00 // [7:6]=00b
	CipherAlgTagBitIntegrityMask  uint8 = 0x40 // [7:6]=01b
	CipherAlgTagBitEncryptionMask uint8 = 0x80 // [7:6]=10b

	LIST_ALGORITHMS_BY_CIPHER_SUITE uint8 = 0x80
)

// getCipherSuiteAlgorithms returns AuthAlg, IntegrityAlg and CryptAlg of the specified cipherSuiteID.
func getCipherSuiteAlgorithms(cipherSuiteID CipherSuiteID) (authAlg AuthAlg, integrity IntegrityAlg, encryptionAlg CryptAlg, err error) {
	switch cipherSuiteID {
	case CipherSuiteID0:
		return AuthAlgRAKP_None, IntegrityAlg_None, CryptAlg_None, nil
	case CipherSuiteID1:
		return AuthAlgRAKP_HMAC_SHA1, IntegrityAlg_None, CryptAlg_None, nil
	case CipherSuiteID2:
		return AuthAlgRAKP_HMAC_SHA1, IntegrityAlg_HMAC_SHA1_96, CryptAlg_None, nil
	case CipherSuiteID3:
		return AuthAlgRAKP_HMAC_SHA1, IntegrityAlg_HMAC_SHA1_96, CryptAlg_AES_CBC_128, nil
	case CipherSuiteID4:
		return AuthAlgRAKP_HMAC_SHA1, IntegrityAlg_HMAC_SHA1_96, CryptAlg_xRC4_128, nil
	case CipherSuiteID5:
		return AuthAlgRAKP_HMAC_SHA1, IntegrityAlg_HMAC_SHA1_96, CryptAlg_xRC4_40, nil
	case CipherSuiteID6:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_None, CryptAlg_None, nil
	case CipherSuiteID7:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_HMAC_MD5_128, CryptAlg_None, nil
	case CipherSuiteID8:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_HMAC_MD5_128, CryptAlg_AES_CBC_128, nil
	case CipherSuiteID9:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_HMAC_MD5_128, CryptAlg_xRC4_128, nil
	case CipherSuiteID10:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_HMAC_MD5_128, CryptAlg_xRC4_40, nil
	case CipherSuiteID11:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_MD5_128, CryptAlg_None, nil
	case CipherSuiteID12:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_MD5_128, CryptAlg_AES_CBC_128, nil
	case CipherSuiteID13:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_MD5_128, CryptAlg_xRC4_128, nil
	case CipherSuiteID14:
		return AuthAlgRAKP_HMAC_MD5, IntegrityAlg_MD5_128, CryptAlg_xRC4_40, nil
	case CipherSuiteID15:
		return AuthAlgRAKP_HMAC_SHA256, IntegrityAlg_None, CryptAlg_None, nil
	case CipherSuiteID16:
		return AuthAlgRAKP_HMAC_SHA256, IntegrityAlg_HMAC_SHA256_128, CryptAlg_None, nil
	case CipherSuiteID17:
		return AuthAlgRAKP_HMAC_SHA256, IntegrityAlg_HMAC_SHA256_128, CryptAlg_AES_CBC_128, nil
	case CipherSuiteID18:
		return AuthAlgRAKP_HMAC_SHA256, IntegrityAlg_HMAC_SHA256_128, CryptAlg_xRC4_128, nil
	case CipherSuiteID19:
		return AuthAlgRAKP_HMAC_SHA256, IntegrityAlg_HMAC_SHA256_128, CryptAlg_xRC4_40, nil
	case CipherSuiteIDReserved:
		return 0, 0, 0, nil
	default:
		return 0, 0, 0, nil
	}
}

// 22.15.1 Cipher Suite Records
// The size of a CipherSuiteRecord is
type CipherSuiteRecord struct {
	// If StartOfRecord is C0h, indicating that the Start Of Record byte is followed by an Cipher Suite ID
	// If StartOfRecord is C1h, indicating that the Start Of Record byte is followed  by a OEM Cipher Suite ID plus OEM IANA
	StartOfRecord uint8

	// a numeric way of identifying the Cipher Suite on the platform
	CipherSuitID CipherSuiteID
	OEMIanaID    uint32 // Least significant byte first. 3-byte IANA for the OEM or body that defined the Cipher Suite.

	// an authentication algorithm number is required for all Cipher Suites.
	// It is possible that a given Cipher Suite may not specify use of an integrity or confidentiality algorithm.
	AuthAlg       uint8   // Tag bits: [7:6]=00b
	IntegrityAlgs []uint8 // Tag bits: [7:6]=01b
	CryptAlgs     []uint8 // Tag bits: [7:6]=10b
}

func (c *Client) findBestCipherSuites(ctx context.Context) []CipherSuiteID {
	cipherSuiteRecords, err := c.GetAllChannelCipherSuites(ctx, ChannelNumberSelf)
	if err != nil {
		return preferredCiphers
	}

	cipherSuiteIDs := make([]CipherSuiteID, len(cipherSuiteRecords))
	for i, cipherSuiteRecord := range cipherSuiteRecords {
		cipherSuiteIDs[i] = cipherSuiteRecord.CipherSuitID
	}
	return sortCipherSuites(cipherSuiteIDs)
}

// sortCipherSuites return cipher suites in order of preference.
// the cipher suite not in the preferredCiphers list would be excluded.
func sortCipherSuites(cipherSuites []CipherSuiteID) []CipherSuiteID {
	sorted := make([]CipherSuiteID, 0)
	for _, preferredCipher := range preferredCiphers {
		for _, cipherSuiteID := range cipherSuites {
			if preferredCipher == cipherSuiteID {
				sorted = append(sorted, cipherSuiteID)
			}
		}
	}

	return sorted
}

var preferredCiphers = []CipherSuiteID{
	// Todo
	// cipher suite best order is chosen with this criteria:
	// xRC4 is bad
	// AES128 is required
	// HMAC-SHA256 > HMAC-SHA1
	// secure authentication > encrypted content

	// With xRC4 out, all cipher suites with MD5 out, and cipher suite 3
	// being required by the spec, the only better defined standard cipher
	// suite is 17. So if SHA256 is available, we should try to use that,
	// otherwise, fall back to 3.

	CipherSuiteID17,

	// IPMI 2.0 spec requires that cipher suite 3 is implemented
	// so we should always be able to fall back to that if better
	// options are not available.
	// CipherSuiteID3 -> 01h, 01h, 01h
	CipherSuiteID3,

	CipherSuiteID15,
	CipherSuiteID16,
	CipherSuiteID18,
	CipherSuiteID19,

	CipherSuiteID6,
	CipherSuiteID7,
	CipherSuiteID8,
	CipherSuiteID11,
	CipherSuiteID12,

	// xRC4 is bad, so we don't use it

	// CipherSuiteID4,
	// CipherSuiteID5,
	// CipherSuiteID9,
	// CipherSuiteID10,
	// CipherSuiteID13,
	// CipherSuiteID14,
}