// Copyright 2018 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef OPENSSL_HEADER_CRYPTO_CPU_ARM_LINUX_H
#define OPENSSL_HEADER_CRYPTO_CPU_ARM_LINUX_H

#include <openssl/base.h>

#include <assert.h>

#include <string_view>

#include "internal.h"


BSSL_NAMESPACE_BEGIN
namespace armcap {

// The cpuinfo parser lives in a header file so it may be accessible from
// cross-platform fuzzers without adding code to those platforms normally.

#define CRYPTO_HWCAP_NEON (1 << 12)

// See /usr/include/asm/hwcap.h on an ARM installation for the source of
// these values.
// We add the prefix "CRYPTO_" to the definitions so as not to collide with
// some versions of glibc (>= 2.41) that expose them through <sys/auxv.h>.
#define CRYPTO_HWCAP2_AES (1 << 0)
#define CRYPTO_HWCAP2_PMULL (1 << 1)
#define CRYPTO_HWCAP2_SHA1 (1 << 2)
#define CRYPTO_HWCAP2_SHA2 (1 << 3)

// SplitStringView finds the first occurrence of |sep| in |in| and, if found,
// sets |*out_left| and |*out_right| to |in| split before and after |sep|, and
// returns true. If not found, it returns false.
inline bool SplitStringView(std::string_view *out_left,
                            std::string_view *out_right, std::string_view in,
                            char sep) {
  auto pos = in.find(sep);
  if (pos == std::string_view::npos) {
    return false;
  }
  *out_left = in.substr(0, pos);
  *out_right = in.substr(pos + 1);
  return true;
}

// GetDelimited reads a |sep|-delimited entry from |s|, writing it to |out| and
// updating |s| to point beyond it. It returns true on success and false if |s|
// is empty. If |s| has no copies of |sep| and is non-empty, it reads the entire
// string to |out|.
inline bool GetDelimited(std::string_view *s, std::string_view *out, char sep) {
  if (s->empty()) {
    return false;
  }
  if (!SplitStringView(out, s, *s, sep)) {
    // |s| had no instances of |sep|. Return the entire string.
    *out = *s;
    *s = std::string_view();
  }
  return true;
}

// TrimStringView removes leading and trailing whitespace from |s|.
inline std::string_view TrimStringView(std::string_view s) {
  size_t pos = s.find_first_not_of(" \t");
  if (pos == std::string_view::npos) {
    return {};
  }
  s = s.substr(pos);
  pos = s.find_last_not_of(" \t");
  assert(pos != std::string_view::npos);
  return s.substr(0, pos + 1);
}

// ExtractCpuinfoField extracts a /proc/cpuinfo field named |field| from |in|.
// If found, it returns the value. Otherwise, it returns the empty string.
inline std::string_view ExtractCpuinfoField(std::string_view in,
                                            std::string_view field) {
  // Process |in| one line at a time.
  std::string_view line;
  while (GetDelimited(&in, &line, '\n')) {
    std::string_view key, value;
    if (!SplitStringView(&key, &value, line, ':')) {
      continue;
    }
    if (TrimStringView(key) == field) {
      return TrimStringView(value);
    }
  }

  return {};
}

// HasListItem treats |list| as a space-separated list of items and returns
// whether |item| is contained in |list|.
inline bool HasListItem(std::string_view list, std::string_view item) {
  std::string_view feature;
  while (GetDelimited(&list, &feature, ' ')) {
    if (feature == item) {
      return true;
    }
  }
  return false;
}

// GetHWCAP2FromCpuinfo returns an equivalent ARM |AT_HWCAP2| value from
// |cpuinfo|.
inline unsigned long GetHWCAP2FromCpuinfo(std::string_view cpuinfo) {
  std::string_view features = ExtractCpuinfoField(cpuinfo, "Features");
  unsigned long ret = 0;
  if (HasListItem(features, "aes")) {
    ret |= CRYPTO_HWCAP2_AES;
  }
  if (HasListItem(features, "pmull")) {
    ret |= CRYPTO_HWCAP2_PMULL;
  }
  if (HasListItem(features, "sha1")) {
    ret |= CRYPTO_HWCAP2_SHA1;
  }
  if (HasListItem(features, "sha2")) {
    ret |= CRYPTO_HWCAP2_SHA2;
  }
  return ret;
}

}  // namespace armcap
BSSL_NAMESPACE_END

#endif  // OPENSSL_HEADER_CRYPTO_CPU_ARM_LINUX_H
