aboutsummaryrefslogtreecommitdiff
path: root/stm-sdram.h
AgeCommit message (Expand)Author
2016-05-23SDRAM initialization and test code from Pavel.Fredrik Thulin
id='n14' href='#n14'>14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
/*
 * hal_rpc.c
 * ---------
 * Remote procedure call public API implementation.
 *
 * Authors: Rob Austein
 * Copyright (c) 2015-2016, NORDUnet A/S All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * - Neither the name of the NORDUnet nor the names of its contributors may
 *   be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "hal.h"
#include "hal_internal.h"

const hal_hash_handle_t hal_hash_handle_none = {HAL_HANDLE_NONE};

/*
 * PIN lengths.  These are somewhat arbitrary, and the current values
 * are really placeholders until we figure out something better.
 * Minimum length here is almost certainly too short for production
 * use, we allow it because most test programs fail if we insist on a
 * PIN long enough to have any real security.
 */

#ifndef HAL_PIN_MINIMUM_LENGTH
#define HAL_PIN_MINIMUM_LENGTH          4
#endif

#ifndef HAL_PIN_MAXIMUM_LENGTH
#define HAL_PIN_MAXIMUM_LENGTH          4096
#endif

const size_t hal_rpc_min_pin_length = HAL_PIN_MINIMUM_LENGTH;
const size_t hal_rpc_max_pin_length = HAL_PIN_MAXIMUM_LENGTH;

static inline int check_pkey_type(const hal_key_type_t type)
{
  switch (type) {
  case HAL_KEY_TYPE_RSA_PRIVATE:
  case HAL_KEY_TYPE_RSA_PUBLIC:
  case HAL_KEY_TYPE_EC_PRIVATE:
  case HAL_KEY_TYPE_EC_PUBLIC:
    return 1;
  default:
    return 0;
  }
}

static inline int check_pkey_flags(const hal_key_flags_t flags)
{
  return (flags &~ (HAL_KEY_FLAG_USAGE_DIGITALSIGNATURE |
                    HAL_KEY_FLAG_USAGE_KEYENCIPHERMENT  |
                    HAL_KEY_FLAG_USAGE_DATAENCIPHERMENT |
                    HAL_KEY_FLAG_PROXIMATE)) == 0;
}

static inline int check_pkey_type_curve_flags(const hal_key_type_t type,
                                              const hal_curve_name_t curve,
                                              const hal_key_flags_t flags)
{
  if (!check_pkey_flags(flags))
    return 0;

  switch (type) {

  case HAL_KEY_TYPE_RSA_PRIVATE:
  case HAL_KEY_TYPE_RSA_PUBLIC:
    return curve == HAL_CURVE_NONE;

  case HAL_KEY_TYPE_EC_PRIVATE:
  case HAL_KEY_TYPE_EC_PUBLIC:
    switch (curve) {
    case HAL_CURVE_P256:
    case HAL_CURVE_P384:
    case HAL_CURVE_P521:
      return 1;
    default:
      return 0;
    }

  default:
    return 0;
  }
}


hal_error_t hal_rpc_get_version(uint32_t *version)
{
  return hal_rpc_misc_dispatch->get_version(version);
}

hal_error_t hal_rpc_get_random(void *buffer, const size_t length)
{
  if (buffer == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  if (length == 0)
    return HAL_OK;
  return hal_rpc_misc_dispatch->get_random(buffer, length);
}

hal_error_t hal_rpc_set_pin(const hal_client_handle_t client,
                            const hal_user_t user,
                            const char * const newpin, const size_t newpin_len)
{
  if (newpin == NULL ||
      newpin_len < hal_rpc_min_pin_length ||
      newpin_len > hal_rpc_max_pin_length ||
      (user != HAL_USER_NORMAL && user != HAL_USER_SO && user != HAL_USER_WHEEL))
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_misc_dispatch->set_pin(client, user, newpin, newpin_len);
}

hal_error_t hal_rpc_login(const hal_client_handle_t client,
                          const hal_user_t user,
                          const char * const pin, const size_t pin_len)
{
  if (pin == NULL ||
      pin_len < hal_rpc_min_pin_length ||
      pin_len > hal_rpc_max_pin_length ||
      (user != HAL_USER_NORMAL && user != HAL_USER_SO && user != HAL_USER_WHEEL))
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_misc_dispatch->login(client, user, pin, pin_len);
}

hal_error_t hal_rpc_logout(const hal_client_handle_t client)
{
  return hal_rpc_misc_dispatch->logout(client);
}

hal_error_t hal_rpc_logout_all(void)
{
  return hal_rpc_misc_dispatch->logout_all();
}

hal_error_t hal_rpc_is_logged_in(const hal_client_handle_t client,
                                 const hal_user_t user)
{
  if (user != HAL_USER_NORMAL && user != HAL_USER_SO && user != HAL_USER_WHEEL)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_misc_dispatch->is_logged_in(client, user);
}

hal_error_t hal_rpc_hash_get_digest_length(const hal_digest_algorithm_t alg, size_t *length)
{
  if (length == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_hash_dispatch->get_digest_length(alg, length);
}

hal_error_t hal_rpc_hash_get_digest_algorithm_id(const hal_digest_algorithm_t alg,
                                                 uint8_t *id, size_t *len, const size_t len_max)
{
  return hal_rpc_hash_dispatch->get_digest_algorithm_id(alg, id, len, len_max);
}

hal_error_t hal_rpc_hash_get_algorithm(const hal_hash_handle_t hash, hal_digest_algorithm_t *alg)
{
  if (hash.handle == HAL_HANDLE_NONE || alg == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_hash_dispatch->get_algorithm(hash, alg);
}

hal_error_t hal_rpc_hash_initialize(const hal_client_handle_t client,
                                    const hal_session_handle_t session,
                                    hal_hash_handle_t *hash,
                                    const hal_digest_algorithm_t alg,
                                    const uint8_t * const key, const size_t key_len)
{
  if (hash == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_hash_dispatch->initialize(client, session, hash, alg, key, key_len);
}

hal_error_t hal_rpc_hash_update(const hal_hash_handle_t hash,
                                const uint8_t * data, const size_t length)
{
  if (hash.handle == HAL_HANDLE_NONE || data == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  if (length == 0)
    return HAL_OK;
  return hal_rpc_hash_dispatch->update(hash, data, length);
}

hal_error_t hal_rpc_hash_finalize(const hal_hash_handle_t hash,
                                  uint8_t *digest, const size_t length)
{
  if (hash.handle == HAL_HANDLE_NONE || digest == NULL || length == 0)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_hash_dispatch->finalize(hash, digest, length);
}

hal_error_t hal_rpc_pkey_load(const hal_client_handle_t client,
                              const hal_session_handle_t session,
                              hal_pkey_handle_t *pkey,
                              const hal_key_type_t type,
                              const hal_curve_name_t curve,
                              const uint8_t * const name, const size_t name_len,
                              const uint8_t * const der, const size_t der_len,
                              const hal_key_flags_t flags)
{
  if (pkey == NULL || name == NULL || der == NULL || der_len == 0 ||
      !check_pkey_type_curve_flags(type, curve, flags))
    return HAL_ERROR_BAD_ARGUMENTS;
  if (name_len > HAL_RPC_PKEY_NAME_MAX)
    return HAL_ERROR_KEY_NAME_TOO_LONG;
  return hal_rpc_pkey_dispatch->load(client, session, pkey, type, curve, name, name_len, der, der_len, flags);
}

hal_error_t hal_rpc_pkey_find(const hal_client_handle_t client,
                              const hal_session_handle_t session,
                              hal_pkey_handle_t *pkey,
                              const hal_key_type_t type,
                              const uint8_t * const name, const size_t name_len,
                              const hal_key_flags_t flags)
{
  if (pkey == NULL || name == NULL || !check_pkey_type(type))
    return HAL_ERROR_BAD_ARGUMENTS;
  if (name_len > HAL_RPC_PKEY_NAME_MAX)
    return HAL_ERROR_KEY_NAME_TOO_LONG;
  return hal_rpc_pkey_dispatch->find(client, session, pkey, type, name, name_len, flags);
}

hal_error_t hal_rpc_pkey_generate_rsa(const hal_client_handle_t client,
                                      const hal_session_handle_t session,
                                      hal_pkey_handle_t *pkey,
                                      const uint8_t * const name, const size_t name_len,
                                      const unsigned key_len,
                                      const uint8_t * const exp, const size_t exp_len,
                                      const hal_key_flags_t flags)
{
  if (pkey == NULL || name == NULL || key_len == 0 || (key_len & 7) != 0 ||
      exp == NULL || exp_len == 0 || !check_pkey_flags(flags))
    return HAL_ERROR_BAD_ARGUMENTS;
  if (name_len > HAL_RPC_PKEY_NAME_MAX)
    return HAL_ERROR_KEY_NAME_TOO_LONG;
  return hal_rpc_pkey_dispatch->generate_rsa(client, session, pkey, name, name_len, key_len, exp, exp_len, flags);
}

hal_error_t hal_rpc_pkey_generate_ec(const hal_client_handle_t client,
                                     const hal_session_handle_t session,
                                     hal_pkey_handle_t *pkey,
                                     const uint8_t * const name, const size_t name_len,
                                     const hal_curve_name_t curve,
                                     const hal_key_flags_t flags)
{
  if (pkey == NULL || name == NULL ||
      !check_pkey_type_curve_flags(HAL_KEY_TYPE_EC_PRIVATE, curve, flags))
    return HAL_ERROR_BAD_ARGUMENTS;
  if (name_len > HAL_RPC_PKEY_NAME_MAX)
    return HAL_ERROR_KEY_NAME_TOO_LONG;
  return hal_rpc_pkey_dispatch->generate_ec(client, session, pkey, name, name_len, curve, flags);
}

hal_error_t hal_rpc_pkey_close(const hal_pkey_handle_t pkey)
{
  return hal_rpc_pkey_dispatch->close(pkey);
}

hal_error_t hal_rpc_pkey_delete(const hal_pkey_handle_t pkey)
{
  return hal_rpc_pkey_dispatch->delete(pkey);
}

hal_error_t hal_rpc_pkey_rename(const hal_pkey_handle_t pkey,
                                const uint8_t * const name, const size_t name_len)
{
  if (name == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  if (name_len > HAL_RPC_PKEY_NAME_MAX)
    return HAL_ERROR_KEY_NAME_TOO_LONG;
  return hal_rpc_pkey_dispatch->rename(pkey, name, name_len);
}

hal_error_t hal_rpc_pkey_get_key_type(const hal_pkey_handle_t pkey,
                                      hal_key_type_t *type)
{
  if (type == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_pkey_dispatch->get_key_type(pkey, type);
}

hal_error_t hal_rpc_pkey_get_key_flags(const hal_pkey_handle_t pkey,
                                       hal_key_flags_t *flags)
{
  if (flags == NULL)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_pkey_dispatch->get_key_flags(pkey, flags);
}

size_t hal_rpc_pkey_get_public_key_len(const hal_pkey_handle_t pkey)
{
  return hal_rpc_pkey_dispatch->get_public_key_len(pkey);
}

hal_error_t hal_rpc_pkey_get_public_key(const hal_pkey_handle_t pkey,
                                        uint8_t *der, size_t *der_len, const size_t der_max)
{
  if (der == NULL || der_len == NULL || der_max == 0)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_pkey_dispatch->get_public_key(pkey, der, der_len, der_max);
}

hal_error_t hal_rpc_pkey_sign(const hal_session_handle_t session,
                              const hal_pkey_handle_t pkey,
                              const hal_hash_handle_t hash,
                              const uint8_t * const input,  const size_t input_len,
                              uint8_t * signature, size_t *signature_len, const size_t signature_max)
{
  if (signature == NULL || signature_len == NULL || signature_max == 0 ||
      (hash.handle == HAL_HANDLE_NONE) == (input == NULL || input_len == 0))
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_pkey_dispatch->sign(session, pkey, hash, input,  input_len, signature, signature_len, signature_max);
}

hal_error_t hal_rpc_pkey_verify(const hal_session_handle_t session,
                                const hal_pkey_handle_t pkey,
                                const hal_hash_handle_t hash,
                                const uint8_t * const input, const size_t input_len,
                                const uint8_t * const signature, const size_t signature_len)
{
  if (signature == NULL || signature_len == 0 ||
      (hash.handle == HAL_HANDLE_NONE) == (input == NULL || input_len == 0))
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_pkey_dispatch->verify(session, pkey, hash, input, input_len, signature, signature_len);
}

hal_error_t hal_rpc_pkey_list(hal_pkey_info_t *result,
                              unsigned *result_len,
                              const unsigned result_max,
                              hal_key_flags_t flags)
{
  if (result == NULL || result_len == NULL || result_max == 0)
    return HAL_ERROR_BAD_ARGUMENTS;
  return hal_rpc_pkey_dispatch->list(result, result_len, result_max, flags);
}

/*
 * Local variables:
 * indent-tabs-mode: nil
 * End:
 */