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