xref: /aosp_15_r20/external/tink/go/subtle/subtle.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1*e7b1675dSTing-Kang Chang// Copyright 2020 Google LLC
2*e7b1675dSTing-Kang Chang//
3*e7b1675dSTing-Kang Chang// Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang// you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang// You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang//
7*e7b1675dSTing-Kang Chang//      http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang//
9*e7b1675dSTing-Kang Chang// Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang// distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang// See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang// limitations under the License.
14*e7b1675dSTing-Kang Chang//
15*e7b1675dSTing-Kang Chang////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang// Package subtle provides common methods needed in subtle implementations.
18*e7b1675dSTing-Kang Changpackage subtle
19*e7b1675dSTing-Kang Chang
20*e7b1675dSTing-Kang Changimport (
21*e7b1675dSTing-Kang Chang	"crypto/elliptic"
22*e7b1675dSTing-Kang Chang	"crypto/sha1"
23*e7b1675dSTing-Kang Chang	"crypto/sha256"
24*e7b1675dSTing-Kang Chang	"crypto/sha512"
25*e7b1675dSTing-Kang Chang	"encoding/hex"
26*e7b1675dSTing-Kang Chang	"errors"
27*e7b1675dSTing-Kang Chang	"hash"
28*e7b1675dSTing-Kang Chang	"math/big"
29*e7b1675dSTing-Kang Chang)
30*e7b1675dSTing-Kang Chang
31*e7b1675dSTing-Kang Changvar errNilHashFunc = errors.New("nil hash function")
32*e7b1675dSTing-Kang Chang
33*e7b1675dSTing-Kang Chang// hashDigestSize maps hash algorithms to their digest size in bytes.
34*e7b1675dSTing-Kang Changvar hashDigestSize = map[string]uint32{
35*e7b1675dSTing-Kang Chang	"SHA1":   uint32(20),
36*e7b1675dSTing-Kang Chang	"SHA224": uint32(28),
37*e7b1675dSTing-Kang Chang	"SHA256": uint32(32),
38*e7b1675dSTing-Kang Chang	"SHA384": uint32(48),
39*e7b1675dSTing-Kang Chang	"SHA512": uint32(64),
40*e7b1675dSTing-Kang Chang}
41*e7b1675dSTing-Kang Chang
42*e7b1675dSTing-Kang Chang// GetHashDigestSize returns the digest size of the specified hash algorithm.
43*e7b1675dSTing-Kang Changfunc GetHashDigestSize(hash string) (uint32, error) {
44*e7b1675dSTing-Kang Chang	digestSize, ok := hashDigestSize[hash]
45*e7b1675dSTing-Kang Chang	if !ok {
46*e7b1675dSTing-Kang Chang		return 0, errors.New("invalid hash algorithm")
47*e7b1675dSTing-Kang Chang	}
48*e7b1675dSTing-Kang Chang	return digestSize, nil
49*e7b1675dSTing-Kang Chang}
50*e7b1675dSTing-Kang Chang
51*e7b1675dSTing-Kang Chang// TODO(ckl): Perhaps return an explicit error instead of ""/nil for the
52*e7b1675dSTing-Kang Chang// following functions.
53*e7b1675dSTing-Kang Chang
54*e7b1675dSTing-Kang Chang// ConvertHashName converts different forms of a hash name to the
55*e7b1675dSTing-Kang Chang// hash name that tink recognizes.
56*e7b1675dSTing-Kang Changfunc ConvertHashName(name string) string {
57*e7b1675dSTing-Kang Chang	switch name {
58*e7b1675dSTing-Kang Chang	case "SHA-224":
59*e7b1675dSTing-Kang Chang		return "SHA224"
60*e7b1675dSTing-Kang Chang	case "SHA-256":
61*e7b1675dSTing-Kang Chang		return "SHA256"
62*e7b1675dSTing-Kang Chang	case "SHA-384":
63*e7b1675dSTing-Kang Chang		return "SHA384"
64*e7b1675dSTing-Kang Chang	case "SHA-512":
65*e7b1675dSTing-Kang Chang		return "SHA512"
66*e7b1675dSTing-Kang Chang	case "SHA-1":
67*e7b1675dSTing-Kang Chang		return "SHA1"
68*e7b1675dSTing-Kang Chang	default:
69*e7b1675dSTing-Kang Chang		return ""
70*e7b1675dSTing-Kang Chang	}
71*e7b1675dSTing-Kang Chang}
72*e7b1675dSTing-Kang Chang
73*e7b1675dSTing-Kang Chang// ConvertCurveName converts different forms of a curve name to the
74*e7b1675dSTing-Kang Chang// name that tink recognizes.
75*e7b1675dSTing-Kang Changfunc ConvertCurveName(name string) string {
76*e7b1675dSTing-Kang Chang	switch name {
77*e7b1675dSTing-Kang Chang	case "secp256r1", "P-256":
78*e7b1675dSTing-Kang Chang		return "NIST_P256"
79*e7b1675dSTing-Kang Chang	case "secp384r1", "P-384":
80*e7b1675dSTing-Kang Chang		return "NIST_P384"
81*e7b1675dSTing-Kang Chang	case "secp521r1", "P-521":
82*e7b1675dSTing-Kang Chang		return "NIST_P521"
83*e7b1675dSTing-Kang Chang	default:
84*e7b1675dSTing-Kang Chang		return ""
85*e7b1675dSTing-Kang Chang	}
86*e7b1675dSTing-Kang Chang}
87*e7b1675dSTing-Kang Chang
88*e7b1675dSTing-Kang Chang// GetHashFunc returns the corresponding hash function of the given hash name.
89*e7b1675dSTing-Kang Changfunc GetHashFunc(hash string) func() hash.Hash {
90*e7b1675dSTing-Kang Chang	switch hash {
91*e7b1675dSTing-Kang Chang	case "SHA1":
92*e7b1675dSTing-Kang Chang		return sha1.New
93*e7b1675dSTing-Kang Chang	case "SHA224":
94*e7b1675dSTing-Kang Chang		return sha256.New224
95*e7b1675dSTing-Kang Chang	case "SHA256":
96*e7b1675dSTing-Kang Chang		return sha256.New
97*e7b1675dSTing-Kang Chang	case "SHA384":
98*e7b1675dSTing-Kang Chang		return sha512.New384
99*e7b1675dSTing-Kang Chang	case "SHA512":
100*e7b1675dSTing-Kang Chang		return sha512.New
101*e7b1675dSTing-Kang Chang	default:
102*e7b1675dSTing-Kang Chang		return nil
103*e7b1675dSTing-Kang Chang	}
104*e7b1675dSTing-Kang Chang}
105*e7b1675dSTing-Kang Chang
106*e7b1675dSTing-Kang Chang// GetCurve returns the curve object that corresponds to the given curve type.
107*e7b1675dSTing-Kang Chang// It returns null if the curve type is not supported.
108*e7b1675dSTing-Kang Changfunc GetCurve(curve string) elliptic.Curve {
109*e7b1675dSTing-Kang Chang	switch curve {
110*e7b1675dSTing-Kang Chang	case "NIST_P256":
111*e7b1675dSTing-Kang Chang		return elliptic.P256()
112*e7b1675dSTing-Kang Chang	case "NIST_P384":
113*e7b1675dSTing-Kang Chang		return elliptic.P384()
114*e7b1675dSTing-Kang Chang	case "NIST_P521":
115*e7b1675dSTing-Kang Chang		return elliptic.P521()
116*e7b1675dSTing-Kang Chang	default:
117*e7b1675dSTing-Kang Chang		return nil
118*e7b1675dSTing-Kang Chang	}
119*e7b1675dSTing-Kang Chang}
120*e7b1675dSTing-Kang Chang
121*e7b1675dSTing-Kang Chang// ComputeHash calculates a hash of the given data using the given hash function.
122*e7b1675dSTing-Kang Changfunc ComputeHash(hashFunc func() hash.Hash, data []byte) ([]byte, error) {
123*e7b1675dSTing-Kang Chang	if hashFunc == nil {
124*e7b1675dSTing-Kang Chang		return nil, errNilHashFunc
125*e7b1675dSTing-Kang Chang	}
126*e7b1675dSTing-Kang Chang	h := hashFunc()
127*e7b1675dSTing-Kang Chang
128*e7b1675dSTing-Kang Chang	_, err := h.Write(data)
129*e7b1675dSTing-Kang Chang	if err != nil {
130*e7b1675dSTing-Kang Chang		return nil, err
131*e7b1675dSTing-Kang Chang	}
132*e7b1675dSTing-Kang Chang
133*e7b1675dSTing-Kang Chang	return h.Sum(nil), nil
134*e7b1675dSTing-Kang Chang}
135*e7b1675dSTing-Kang Chang
136*e7b1675dSTing-Kang Chang// NewBigIntFromHex returns a big integer from a hex string.
137*e7b1675dSTing-Kang Changfunc NewBigIntFromHex(s string) (*big.Int, error) {
138*e7b1675dSTing-Kang Chang	if len(s)%2 == 1 {
139*e7b1675dSTing-Kang Chang		s = "0" + s
140*e7b1675dSTing-Kang Chang	}
141*e7b1675dSTing-Kang Chang	b, err := hex.DecodeString(s)
142*e7b1675dSTing-Kang Chang	if err != nil {
143*e7b1675dSTing-Kang Chang		return nil, err
144*e7b1675dSTing-Kang Chang	}
145*e7b1675dSTing-Kang Chang	ret := new(big.Int).SetBytes(b)
146*e7b1675dSTing-Kang Chang	return ret, nil
147*e7b1675dSTing-Kang Chang}
148