[GCrypt] Gather SUBTLE_CRYPTO utility functions in a single header
[WebKit-https.git] / Source / WebCore / crypto / gcrypt / GCryptUtilities.h
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2017 Metrological Group B.V.
4  * Copyright (C) 2017 Igalia S.L.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25  * THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "CryptoAlgorithmIdentifier.h"
29 #include <gcrypt.h>
30 #include <pal/crypto/CryptoDigest.h>
31 #include <pal/crypto/gcrypt/Handle.h>
32 #include <pal/crypto/gcrypt/Utilities.h>
33
34 namespace WebCore {
35
36 static inline std::optional<const char*> hashAlgorithmName(CryptoAlgorithmIdentifier identifier)
37 {
38     switch (identifier) {
39     case CryptoAlgorithmIdentifier::SHA_1:
40         return "sha1";
41     case CryptoAlgorithmIdentifier::SHA_224:
42         return "sha224";
43     case CryptoAlgorithmIdentifier::SHA_256:
44         return "sha256";
45     case CryptoAlgorithmIdentifier::SHA_384:
46         return "sha384";
47     case CryptoAlgorithmIdentifier::SHA_512:
48         return "sha512";
49     default:
50         return std::nullopt;
51     }
52 }
53
54 static inline std::optional<int> hmacAlgorithm(CryptoAlgorithmIdentifier identifier)
55 {
56     switch (identifier) {
57     case CryptoAlgorithmIdentifier::SHA_1:
58         return GCRY_MAC_HMAC_SHA1;
59     case CryptoAlgorithmIdentifier::SHA_224:
60         return GCRY_MAC_HMAC_SHA224;
61     case CryptoAlgorithmIdentifier::SHA_256:
62         return GCRY_MAC_HMAC_SHA256;
63     case CryptoAlgorithmIdentifier::SHA_384:
64         return GCRY_MAC_HMAC_SHA384;
65     case CryptoAlgorithmIdentifier::SHA_512:
66         return GCRY_MAC_HMAC_SHA512;
67     default:
68         return std::nullopt;
69     }
70 }
71
72 static inline std::optional<int> digestAlgorithm(CryptoAlgorithmIdentifier identifier)
73 {
74     switch (identifier) {
75     case CryptoAlgorithmIdentifier::SHA_1:
76         return GCRY_MD_SHA1;
77     case CryptoAlgorithmIdentifier::SHA_224:
78         return GCRY_MD_SHA224;
79     case CryptoAlgorithmIdentifier::SHA_256:
80         return GCRY_MD_SHA256;
81     case CryptoAlgorithmIdentifier::SHA_384:
82         return GCRY_MD_SHA384;
83     case CryptoAlgorithmIdentifier::SHA_512:
84         return GCRY_MD_SHA512;
85     default:
86         return std::nullopt;
87     }
88 }
89
90 static inline std::optional<PAL::CryptoDigest::Algorithm> hashCryptoDigestAlgorithm(CryptoAlgorithmIdentifier identifier)
91 {
92     switch (identifier) {
93     case CryptoAlgorithmIdentifier::SHA_1:
94         return PAL::CryptoDigest::Algorithm::SHA_1;
95     case CryptoAlgorithmIdentifier::SHA_224:
96         return PAL::CryptoDigest::Algorithm::SHA_224;
97     case CryptoAlgorithmIdentifier::SHA_256:
98         return PAL::CryptoDigest::Algorithm::SHA_256;
99     case CryptoAlgorithmIdentifier::SHA_384:
100         return PAL::CryptoDigest::Algorithm::SHA_384;
101     case CryptoAlgorithmIdentifier::SHA_512:
102         return PAL::CryptoDigest::Algorithm::SHA_512;
103     default:
104         return std::nullopt;
105     }
106 }
107
108 static inline std::optional<Vector<uint8_t>> mpiData(gcry_sexp_t paramSexp)
109 {
110     // Retrieve the MPI value stored in the s-expression: (name mpi-data)
111     PAL::GCrypt::Handle<gcry_mpi_t> paramMPI(gcry_sexp_nth_mpi(paramSexp, 1, GCRYMPI_FMT_USG));
112     if (!paramMPI)
113         return std::nullopt;
114
115     // Query the data length first to properly prepare the buffer.
116     size_t dataLength = 0;
117     gcry_error_t error = gcry_mpi_print(GCRYMPI_FMT_USG, nullptr, 0, &dataLength, paramMPI);
118     if (error != GPG_ERR_NO_ERROR) {
119         PAL::GCrypt::logError(error);
120         return std::nullopt;
121     }
122
123     // Finally, copy the MPI data into a properly-sized buffer.
124     Vector<uint8_t> output(dataLength);
125     error = gcry_mpi_print(GCRYMPI_FMT_USG, output.data(), output.size(), nullptr, paramMPI);
126     if (error != GPG_ERR_NO_ERROR) {
127         PAL::GCrypt::logError(error);
128         return std::nullopt;
129     }
130
131     return output;
132 }
133
134 } // namespace WebCore