1 1.1 christos /* 2 1.1 christos * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1 christos /* Dispatch functions for ccm mode */ 11 1.1 christos 12 1.1 christos #include <openssl/proverr.h> 13 1.1 christos #include "prov/ciphercommon.h" 14 1.1 christos #include "prov/ciphercommon_ccm.h" 15 1.1 christos #include "prov/providercommon.h" 16 1.1 christos 17 1.1 christos static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out, 18 1.1.1.2 christos size_t *padlen, const unsigned char *in, 19 1.1.1.2 christos size_t len); 20 1.1 christos 21 1.1 christos static int ccm_tls_init(PROV_CCM_CTX *ctx, unsigned char *aad, size_t alen) 22 1.1 christos { 23 1.1 christos size_t len; 24 1.1 christos 25 1.1 christos if (!ossl_prov_is_running() || alen != EVP_AEAD_TLS1_AAD_LEN) 26 1.1 christos return 0; 27 1.1 christos 28 1.1 christos /* Save the aad for later use. */ 29 1.1 christos memcpy(ctx->buf, aad, alen); 30 1.1 christos ctx->tls_aad_len = alen; 31 1.1 christos 32 1.1 christos len = ctx->buf[alen - 2] << 8 | ctx->buf[alen - 1]; 33 1.1 christos if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN) 34 1.1 christos return 0; 35 1.1 christos 36 1.1 christos /* Correct length for explicit iv. */ 37 1.1 christos len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; 38 1.1 christos 39 1.1 christos if (!ctx->enc) { 40 1.1 christos if (len < ctx->m) 41 1.1 christos return 0; 42 1.1 christos /* Correct length for tag. */ 43 1.1 christos len -= ctx->m; 44 1.1 christos } 45 1.1 christos ctx->buf[alen - 2] = (unsigned char)(len >> 8); 46 1.1 christos ctx->buf[alen - 1] = (unsigned char)(len & 0xff); 47 1.1 christos 48 1.1 christos /* Extra padding: tag appended to record. */ 49 1.1 christos return ctx->m; 50 1.1 christos } 51 1.1 christos 52 1.1 christos static int ccm_tls_iv_set_fixed(PROV_CCM_CTX *ctx, unsigned char *fixed, 53 1.1.1.2 christos size_t flen) 54 1.1 christos { 55 1.1 christos if (flen != EVP_CCM_TLS_FIXED_IV_LEN) 56 1.1 christos return 0; 57 1.1 christos 58 1.1 christos /* Copy to first part of the iv. */ 59 1.1 christos memcpy(ctx->iv, fixed, flen); 60 1.1 christos return 1; 61 1.1 christos } 62 1.1 christos 63 1.1 christos static size_t ccm_get_ivlen(PROV_CCM_CTX *ctx) 64 1.1 christos { 65 1.1 christos return 15 - ctx->l; 66 1.1 christos } 67 1.1 christos 68 1.1 christos int ossl_ccm_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 69 1.1 christos { 70 1.1 christos PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; 71 1.1 christos const OSSL_PARAM *p; 72 1.1 christos size_t sz; 73 1.1 christos 74 1.1 christos if (ossl_param_is_empty(params)) 75 1.1 christos return 1; 76 1.1 christos 77 1.1 christos p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); 78 1.1 christos if (p != NULL) { 79 1.1 christos if (p->data_type != OSSL_PARAM_OCTET_STRING) { 80 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 81 1.1 christos return 0; 82 1.1 christos } 83 1.1 christos if ((p->data_size & 1) || (p->data_size < 4) || p->data_size > 16) { 84 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH); 85 1.1 christos return 0; 86 1.1 christos } 87 1.1 christos 88 1.1 christos if (p->data != NULL) { 89 1.1 christos if (ctx->enc) { 90 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED); 91 1.1 christos return 0; 92 1.1 christos } 93 1.1 christos memcpy(ctx->buf, p->data, p->data_size); 94 1.1 christos ctx->tag_set = 1; 95 1.1 christos } 96 1.1 christos ctx->m = p->data_size; 97 1.1 christos } 98 1.1 christos 99 1.1 christos p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_IVLEN); 100 1.1 christos if (p != NULL) { 101 1.1 christos size_t ivlen; 102 1.1 christos 103 1.1 christos if (!OSSL_PARAM_get_size_t(p, &sz)) { 104 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 105 1.1 christos return 0; 106 1.1 christos } 107 1.1 christos ivlen = 15 - sz; 108 1.1 christos if (ivlen < 2 || ivlen > 8) { 109 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); 110 1.1 christos return 0; 111 1.1 christos } 112 1.1 christos if (ctx->l != ivlen) { 113 1.1 christos ctx->l = ivlen; 114 1.1 christos ctx->iv_set = 0; 115 1.1 christos } 116 1.1 christos } 117 1.1 christos 118 1.1 christos p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD); 119 1.1 christos if (p != NULL) { 120 1.1 christos if (p->data_type != OSSL_PARAM_OCTET_STRING) { 121 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 122 1.1 christos return 0; 123 1.1 christos } 124 1.1 christos sz = ccm_tls_init(ctx, p->data, p->data_size); 125 1.1 christos if (sz == 0) { 126 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DATA); 127 1.1 christos return 0; 128 1.1 christos } 129 1.1 christos ctx->tls_aad_pad_sz = sz; 130 1.1 christos } 131 1.1 christos 132 1.1 christos p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED); 133 1.1 christos if (p != NULL) { 134 1.1 christos if (p->data_type != OSSL_PARAM_OCTET_STRING) { 135 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); 136 1.1 christos return 0; 137 1.1 christos } 138 1.1 christos if (ccm_tls_iv_set_fixed(ctx, p->data, p->data_size) == 0) { 139 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); 140 1.1 christos return 0; 141 1.1 christos } 142 1.1 christos } 143 1.1 christos 144 1.1 christos return 1; 145 1.1 christos } 146 1.1 christos 147 1.1 christos int ossl_ccm_get_ctx_params(void *vctx, OSSL_PARAM params[]) 148 1.1 christos { 149 1.1 christos PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; 150 1.1 christos OSSL_PARAM *p; 151 1.1 christos 152 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); 153 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, ccm_get_ivlen(ctx))) { 154 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 155 1.1 christos return 0; 156 1.1 christos } 157 1.1 christos 158 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN); 159 1.1 christos if (p != NULL) { 160 1.1 christos size_t m = ctx->m; 161 1.1 christos 162 1.1 christos if (!OSSL_PARAM_set_size_t(p, m)) { 163 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 164 1.1 christos return 0; 165 1.1 christos } 166 1.1 christos } 167 1.1 christos 168 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IV); 169 1.1 christos if (p != NULL) { 170 1.1 christos if (ccm_get_ivlen(ctx) > p->data_size) { 171 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); 172 1.1 christos return 0; 173 1.1 christos } 174 1.1 christos if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) 175 1.1 christos && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { 176 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 177 1.1 christos return 0; 178 1.1 christos } 179 1.1 christos } 180 1.1 christos 181 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_UPDATED_IV); 182 1.1 christos if (p != NULL) { 183 1.1 christos if (ccm_get_ivlen(ctx) > p->data_size) { 184 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); 185 1.1 christos return 0; 186 1.1 christos } 187 1.1 christos if (!OSSL_PARAM_set_octet_string(p, ctx->iv, p->data_size) 188 1.1 christos && !OSSL_PARAM_set_octet_ptr(p, &ctx->iv, p->data_size)) { 189 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 190 1.1 christos return 0; 191 1.1 christos } 192 1.1 christos } 193 1.1 christos 194 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); 195 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) { 196 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 197 1.1 christos return 0; 198 1.1 christos } 199 1.1 christos 200 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD); 201 1.1 christos if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->tls_aad_pad_sz)) { 202 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 203 1.1 christos return 0; 204 1.1 christos } 205 1.1 christos 206 1.1 christos p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG); 207 1.1 christos if (p != NULL) { 208 1.1 christos if (!ctx->enc || !ctx->tag_set) { 209 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET); 210 1.1 christos return 0; 211 1.1 christos } 212 1.1 christos if (p->data_type != OSSL_PARAM_OCTET_STRING) { 213 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); 214 1.1 christos return 0; 215 1.1 christos } 216 1.1 christos if (!ctx->hw->gettag(ctx, p->data, p->data_size)) 217 1.1 christos return 0; 218 1.1 christos ctx->tag_set = 0; 219 1.1 christos ctx->iv_set = 0; 220 1.1 christos ctx->len_set = 0; 221 1.1 christos } 222 1.1 christos return 1; 223 1.1 christos } 224 1.1 christos 225 1.1 christos static int ccm_init(void *vctx, const unsigned char *key, size_t keylen, 226 1.1.1.2 christos const unsigned char *iv, size_t ivlen, 227 1.1.1.2 christos const OSSL_PARAM params[], int enc) 228 1.1 christos { 229 1.1 christos PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; 230 1.1 christos 231 1.1 christos if (!ossl_prov_is_running()) 232 1.1 christos return 0; 233 1.1 christos 234 1.1 christos ctx->enc = enc; 235 1.1 christos 236 1.1 christos if (iv != NULL) { 237 1.1 christos if (ivlen != ccm_get_ivlen(ctx)) { 238 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); 239 1.1 christos return 0; 240 1.1 christos } 241 1.1 christos memcpy(ctx->iv, iv, ivlen); 242 1.1 christos ctx->iv_set = 1; 243 1.1 christos } 244 1.1 christos if (key != NULL) { 245 1.1 christos if (keylen != ctx->keylen) { 246 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 247 1.1 christos return 0; 248 1.1 christos } 249 1.1 christos if (!ctx->hw->setkey(ctx, key, keylen)) 250 1.1 christos return 0; 251 1.1 christos } 252 1.1 christos return ossl_ccm_set_ctx_params(ctx, params); 253 1.1 christos } 254 1.1 christos 255 1.1 christos int ossl_ccm_einit(void *vctx, const unsigned char *key, size_t keylen, 256 1.1.1.2 christos const unsigned char *iv, size_t ivlen, 257 1.1.1.2 christos const OSSL_PARAM params[]) 258 1.1 christos { 259 1.1 christos return ccm_init(vctx, key, keylen, iv, ivlen, params, 1); 260 1.1 christos } 261 1.1 christos 262 1.1 christos int ossl_ccm_dinit(void *vctx, const unsigned char *key, size_t keylen, 263 1.1.1.2 christos const unsigned char *iv, size_t ivlen, 264 1.1.1.2 christos const OSSL_PARAM params[]) 265 1.1 christos { 266 1.1 christos return ccm_init(vctx, key, keylen, iv, ivlen, params, 0); 267 1.1 christos } 268 1.1 christos 269 1.1 christos int ossl_ccm_stream_update(void *vctx, unsigned char *out, size_t *outl, 270 1.1.1.2 christos size_t outsize, const unsigned char *in, 271 1.1.1.2 christos size_t inl) 272 1.1 christos { 273 1.1 christos PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; 274 1.1 christos 275 1.1 christos if (outsize < inl) { 276 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 277 1.1 christos return 0; 278 1.1 christos } 279 1.1 christos 280 1.1 christos if (!ccm_cipher_internal(ctx, out, outl, in, inl)) { 281 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED); 282 1.1 christos return 0; 283 1.1 christos } 284 1.1 christos return 1; 285 1.1 christos } 286 1.1 christos 287 1.1 christos int ossl_ccm_stream_final(void *vctx, unsigned char *out, size_t *outl, 288 1.1.1.2 christos size_t outsize) 289 1.1 christos { 290 1.1 christos PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; 291 1.1 christos int i; 292 1.1 christos 293 1.1 christos if (!ossl_prov_is_running()) 294 1.1 christos return 0; 295 1.1 christos 296 1.1 christos i = ccm_cipher_internal(ctx, out, outl, NULL, 0); 297 1.1 christos if (i <= 0) 298 1.1 christos return 0; 299 1.1 christos 300 1.1 christos *outl = 0; 301 1.1 christos return 1; 302 1.1 christos } 303 1.1 christos 304 1.1 christos int ossl_ccm_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize, 305 1.1.1.2 christos const unsigned char *in, size_t inl) 306 1.1 christos { 307 1.1 christos PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; 308 1.1 christos 309 1.1 christos if (!ossl_prov_is_running()) 310 1.1 christos return 0; 311 1.1 christos 312 1.1 christos if (outsize < inl) { 313 1.1 christos ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 314 1.1 christos return 0; 315 1.1 christos } 316 1.1 christos 317 1.1 christos if (ccm_cipher_internal(ctx, out, outl, in, inl) <= 0) 318 1.1 christos return 0; 319 1.1 christos 320 1.1 christos *outl = inl; 321 1.1 christos return 1; 322 1.1 christos } 323 1.1 christos 324 1.1 christos /* Copy the buffered iv */ 325 1.1 christos static int ccm_set_iv(PROV_CCM_CTX *ctx, size_t mlen) 326 1.1 christos { 327 1.1 christos const PROV_CCM_HW *hw = ctx->hw; 328 1.1 christos 329 1.1 christos if (!hw->setiv(ctx, ctx->iv, ccm_get_ivlen(ctx), mlen)) 330 1.1 christos return 0; 331 1.1 christos ctx->len_set = 1; 332 1.1 christos return 1; 333 1.1 christos } 334 1.1 christos 335 1.1 christos static int ccm_tls_cipher(PROV_CCM_CTX *ctx, 336 1.1.1.2 christos unsigned char *out, size_t *padlen, 337 1.1.1.2 christos const unsigned char *in, size_t len) 338 1.1 christos { 339 1.1 christos int rv = 0; 340 1.1 christos size_t olen = 0; 341 1.1 christos 342 1.1 christos if (!ossl_prov_is_running()) 343 1.1 christos goto err; 344 1.1 christos 345 1.1 christos /* Encrypt/decrypt must be performed in place */ 346 1.1 christos if (in == NULL || out != in || len < EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m) 347 1.1 christos goto err; 348 1.1 christos 349 1.1 christos /* If encrypting set explicit IV from sequence number (start of AAD) */ 350 1.1 christos if (ctx->enc) 351 1.1 christos memcpy(out, ctx->buf, EVP_CCM_TLS_EXPLICIT_IV_LEN); 352 1.1 christos /* Get rest of IV from explicit IV */ 353 1.1 christos memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); 354 1.1 christos /* Correct length value */ 355 1.1 christos len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m; 356 1.1 christos if (!ccm_set_iv(ctx, len)) 357 1.1 christos goto err; 358 1.1 christos 359 1.1 christos /* Use saved AAD */ 360 1.1 christos if (!ctx->hw->setaad(ctx, ctx->buf, ctx->tls_aad_len)) 361 1.1 christos goto err; 362 1.1 christos 363 1.1 christos /* Fix buffer to point to payload */ 364 1.1 christos in += EVP_CCM_TLS_EXPLICIT_IV_LEN; 365 1.1 christos out += EVP_CCM_TLS_EXPLICIT_IV_LEN; 366 1.1 christos if (ctx->enc) { 367 1.1.1.2 christos if (!ctx->hw->auth_encrypt(ctx, in, out, len, out + len, ctx->m)) 368 1.1 christos goto err; 369 1.1 christos olen = len + EVP_CCM_TLS_EXPLICIT_IV_LEN + ctx->m; 370 1.1 christos } else { 371 1.1 christos if (!ctx->hw->auth_decrypt(ctx, in, out, len, 372 1.1.1.2 christos (unsigned char *)in + len, ctx->m)) 373 1.1 christos goto err; 374 1.1 christos olen = len; 375 1.1 christos } 376 1.1 christos rv = 1; 377 1.1 christos err: 378 1.1 christos *padlen = olen; 379 1.1 christos return rv; 380 1.1 christos } 381 1.1 christos 382 1.1 christos static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out, 383 1.1.1.2 christos size_t *padlen, const unsigned char *in, 384 1.1.1.2 christos size_t len) 385 1.1 christos { 386 1.1 christos int rv = 0; 387 1.1 christos size_t olen = 0; 388 1.1 christos const PROV_CCM_HW *hw = ctx->hw; 389 1.1 christos 390 1.1 christos /* If no key set, return error */ 391 1.1 christos if (!ctx->key_set) 392 1.1 christos return 0; 393 1.1 christos 394 1.1 christos if (ctx->tls_aad_len != UNINITIALISED_SIZET) 395 1.1 christos return ccm_tls_cipher(ctx, out, padlen, in, len); 396 1.1 christos 397 1.1 christos /* EVP_*Final() doesn't return any data */ 398 1.1 christos if (in == NULL && out != NULL) 399 1.1 christos goto finish; 400 1.1 christos 401 1.1 christos if (!ctx->iv_set) 402 1.1 christos goto err; 403 1.1 christos 404 1.1 christos if (out == NULL) { 405 1.1 christos if (in == NULL) { 406 1.1 christos if (!ccm_set_iv(ctx, len)) 407 1.1 christos goto err; 408 1.1 christos } else { 409 1.1 christos /* If we have AAD, we need a message length */ 410 1.1 christos if (!ctx->len_set && len) 411 1.1 christos goto err; 412 1.1 christos if (!hw->setaad(ctx, in, len)) 413 1.1 christos goto err; 414 1.1 christos } 415 1.1 christos } else { 416 1.1 christos /* If not set length yet do it */ 417 1.1 christos if (!ctx->len_set && !ccm_set_iv(ctx, len)) 418 1.1 christos goto err; 419 1.1 christos 420 1.1 christos if (ctx->enc) { 421 1.1 christos if (!hw->auth_encrypt(ctx, in, out, len, NULL, 0)) 422 1.1 christos goto err; 423 1.1 christos ctx->tag_set = 1; 424 1.1 christos } else { 425 1.1 christos /* The tag must be set before actually decrypting data */ 426 1.1 christos if (!ctx->tag_set) 427 1.1 christos goto err; 428 1.1 christos 429 1.1 christos if (!hw->auth_decrypt(ctx, in, out, len, ctx->buf, ctx->m)) 430 1.1 christos goto err; 431 1.1 christos /* Finished - reset flags so calling this method again will fail */ 432 1.1 christos ctx->iv_set = 0; 433 1.1 christos ctx->tag_set = 0; 434 1.1 christos ctx->len_set = 0; 435 1.1 christos } 436 1.1 christos } 437 1.1 christos olen = len; 438 1.1 christos finish: 439 1.1 christos rv = 1; 440 1.1 christos err: 441 1.1 christos *padlen = olen; 442 1.1 christos return rv; 443 1.1 christos } 444 1.1 christos 445 1.1 christos void ossl_ccm_initctx(PROV_CCM_CTX *ctx, size_t keybits, const PROV_CCM_HW *hw) 446 1.1 christos { 447 1.1 christos ctx->keylen = keybits / 8; 448 1.1 christos ctx->key_set = 0; 449 1.1 christos ctx->iv_set = 0; 450 1.1 christos ctx->tag_set = 0; 451 1.1 christos ctx->len_set = 0; 452 1.1 christos ctx->l = 8; 453 1.1 christos ctx->m = 12; 454 1.1 christos ctx->tls_aad_len = UNINITIALISED_SIZET; 455 1.1 christos ctx->hw = hw; 456 1.1 christos } 457