1// Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. 2// Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// https://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15 16#include <openssl/ecdh.h> 17 18#include <string.h> 19 20#include <openssl/ec.h> 21#include <openssl/ec_key.h> 22#include <openssl/err.h> 23#include <openssl/mem.h> 24 25#include "../../internal.h" 26#include "../ec/internal.h" 27#include "../service_indicator/internal.h" 28 29 30int ECDH_compute_key_fips(uint8_t *out, size_t out_len, const EC_POINT *pub_key, 31 const EC_KEY *priv_key) { 32 boringssl_ensure_ecc_self_test(); 33 34 if (priv_key->priv_key == NULL) { 35 OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE); 36 return 0; 37 } 38 const EC_SCALAR *const priv = &priv_key->priv_key->scalar; 39 const EC_GROUP *const group = EC_KEY_get0_group(priv_key); 40 if (EC_GROUP_cmp(group, pub_key->group, NULL) != 0) { 41 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 42 return 0; 43 } 44 45 EC_JACOBIAN shared_point; 46 uint8_t buf[EC_MAX_BYTES]; 47 size_t buflen; 48 if (!ec_point_mul_scalar(group, &shared_point, &pub_key->raw, priv) || 49 !ec_get_x_coordinate_as_bytes(group, buf, &buflen, sizeof(buf), 50 &shared_point)) { 51 OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); 52 return 0; 53 } 54 55 FIPS_service_indicator_lock_state(); 56 SHA256_CTX ctx; 57 SHA512_CTX ctx_512; 58 switch (out_len) { 59 case SHA224_DIGEST_LENGTH: 60 BCM_sha224_init(&ctx); 61 BCM_sha224_update(&ctx, buf, buflen); 62 BCM_sha224_final(out, &ctx); 63 break; 64 case SHA256_DIGEST_LENGTH: 65 BCM_sha256_init(&ctx); 66 BCM_sha256_update(&ctx, buf, buflen); 67 BCM_sha256_final(out, &ctx); 68 break; 69 case SHA384_DIGEST_LENGTH: 70 BCM_sha384_init(&ctx_512); 71 BCM_sha384_update(&ctx_512, buf, buflen); 72 BCM_sha384_final(out, &ctx_512); 73 break; 74 case SHA512_DIGEST_LENGTH: 75 BCM_sha512_init(&ctx_512); 76 BCM_sha512_update(&ctx_512, buf, buflen); 77 BCM_sha512_final(out, &ctx_512); 78 break; 79 default: 80 OPENSSL_PUT_ERROR(ECDH, ECDH_R_UNKNOWN_DIGEST_LENGTH); 81 FIPS_service_indicator_unlock_state(); 82 return 0; 83 } 84 FIPS_service_indicator_unlock_state(); 85 86 ECDH_verify_service_indicator(priv_key); 87 return 1; 88} 89