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 17package subtle 18 19import ( 20 "bytes" 21 "crypto/elliptic" 22 "encoding/asn1" 23 "fmt" 24 "math/big" 25) 26 27// asn1encode encodes the given ECDSA signature using ASN.1 encoding. 28func asn1encode(sig *ECDSASignature) ([]byte, error) { 29 ret, err := asn1.Marshal(*sig) 30 if err != nil { 31 return nil, fmt.Errorf("asn.1 encoding failed") 32 } 33 return ret, nil 34} 35 36var errAsn1Decoding = fmt.Errorf("asn.1 decoding failed") 37 38// asn1decode verifies the given ECDSA signature and decodes it if it is valid. 39// Since asn1.Unmarshal() doesn't do a strict verification on its input, it will 40// accept signatures with trailing data. Thus, we add an additional check to make sure 41// that the input follows strict DER encoding: after unmarshalling the signature bytes, 42// we marshal the obtained signature object again. Since DER encoding is deterministic, 43// we expect that the obtained bytes would be equal to the input. 44func asn1decode(b []byte) (*ECDSASignature, error) { 45 // parse the signature 46 sig := new(ECDSASignature) 47 _, err := asn1.Unmarshal(b, sig) 48 if err != nil { 49 return nil, errAsn1Decoding 50 } 51 // encode the signature again 52 encoded, err := asn1.Marshal(*sig) 53 if err != nil { 54 return nil, errAsn1Decoding 55 } 56 if !bytes.Equal(b, encoded) { 57 return nil, errAsn1Decoding 58 } 59 return sig, nil 60} 61 62func ieeeSignatureSize(curveName string) (int, error) { 63 switch curveName { 64 case elliptic.P256().Params().Name: 65 return 64, nil 66 case elliptic.P384().Params().Name: 67 return 96, nil 68 case elliptic.P521().Params().Name: 69 return 132, nil 70 default: 71 return 0, fmt.Errorf("ieeeP1363 unsupported curve name: %q", curveName) 72 } 73} 74 75func ieeeP1363Encode(sig *ECDSASignature, curveName string) ([]byte, error) { 76 sigSize, err := ieeeSignatureSize(curveName) 77 if err != nil { 78 return nil, err 79 } 80 81 enc := make([]byte, sigSize) 82 83 // sigR and sigS must be half the size of the signature. If not, we need to pad them with zeros. 84 offset := 0 85 if len(sig.R.Bytes()) < (sigSize / 2) { 86 offset += (sigSize / 2) - len(sig.R.Bytes()) 87 } 88 // Copy sigR after any zero-padding. 89 copy(enc[offset:], sig.R.Bytes()) 90 91 // Skip the bytes of sigR. 92 offset = sigSize / 2 93 if len(sig.S.Bytes()) < (sigSize / 2) { 94 offset += (sigSize / 2) - len(sig.S.Bytes()) 95 } 96 // Copy sigS after sigR and any zero-padding. 97 copy(enc[offset:], sig.S.Bytes()) 98 99 return enc, nil 100} 101 102func ieeeP1363Decode(encodedBytes []byte) (*ECDSASignature, error) { 103 if len(encodedBytes) == 0 || len(encodedBytes) > 132 || len(encodedBytes)%2 != 0 { 104 return nil, fmt.Errorf("ecdsa: Invalid IEEE_P1363 encoded bytes") 105 } 106 r := new(big.Int).SetBytes(encodedBytes[:len(encodedBytes)/2]) 107 s := new(big.Int).SetBytes(encodedBytes[len(encodedBytes)/2:]) 108 return &ECDSASignature{R: r, S: s}, nil 109} 110