|
16 | 16 | #ifndef NO_SHA256 |
17 | 17 | #include <wolfssl/wolfcrypt/sha256.h> |
18 | 18 | #endif |
| 19 | +#ifndef NO_AES |
| 20 | +#include <wolfssl/wolfcrypt/aes.h> |
| 21 | +#endif |
19 | 22 |
|
20 | 23 | static int swdev_initialized = 0; |
21 | 24 |
|
@@ -179,6 +182,253 @@ static int swdev_sha256(wc_CryptoInfo* info) |
179 | 182 | } |
180 | 183 | #endif /* !NO_SHA256 */ |
181 | 184 |
|
| 185 | +#ifndef NO_AES |
| 186 | +/* Rebuild a software AES shadow from the caller's raw devKey, since the |
| 187 | + * caller's Aes has no software round-key schedule under CB_ONLY_AES. */ |
| 188 | +static int swdev_aes_shadow_init(Aes* shadow, const Aes* aes, int dir) |
| 189 | +{ |
| 190 | + int ret; |
| 191 | + |
| 192 | + if (shadow == NULL || aes == NULL) |
| 193 | + return BAD_FUNC_ARG; |
| 194 | + if (aes->keylen <= 0 || aes->keylen > (int)sizeof(aes->devKey)) |
| 195 | + return BAD_FUNC_ARG; |
| 196 | + |
| 197 | + ret = wc_AesInit(shadow, aes->heap, INVALID_DEVID); |
| 198 | + if (ret != 0) |
| 199 | + return ret; |
| 200 | + |
| 201 | + ret = wc_AesSetKey(shadow, (const byte*)aes->devKey, |
| 202 | + (word32)aes->keylen, (const byte*)aes->reg, dir); |
| 203 | + if (ret != 0) { |
| 204 | + wc_AesFree(shadow); |
| 205 | + return ret; |
| 206 | + } |
| 207 | + |
| 208 | + XMEMCPY(shadow->tmp, aes->tmp, sizeof(shadow->tmp)); |
| 209 | +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ |
| 210 | + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ |
| 211 | + defined(WOLFSSL_AES_CTS) |
| 212 | + shadow->left = aes->left; |
| 213 | +#endif |
| 214 | + |
| 215 | + return 0; |
| 216 | +} |
| 217 | + |
| 218 | +static void swdev_aes_shadow_sync(Aes* dst, const Aes* src) |
| 219 | +{ |
| 220 | + XMEMCPY(dst->reg, src->reg, sizeof(dst->reg)); |
| 221 | + XMEMCPY(dst->tmp, src->tmp, sizeof(dst->tmp)); |
| 222 | +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ |
| 223 | + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ |
| 224 | + defined(WOLFSSL_AES_CTS) |
| 225 | + dst->left = src->left; |
| 226 | +#endif |
| 227 | +} |
| 228 | + |
| 229 | +#ifdef HAVE_AES_CBC |
| 230 | +static int swdev_aes_cbc(wc_CryptoInfo* info) |
| 231 | +{ |
| 232 | + Aes* aes = info->cipher.aescbc.aes; |
| 233 | + byte* out = info->cipher.aescbc.out; |
| 234 | + const byte* in = info->cipher.aescbc.in; |
| 235 | + word32 sz = info->cipher.aescbc.sz; |
| 236 | + Aes shadow; |
| 237 | + int ret; |
| 238 | + |
| 239 | + ret = swdev_aes_shadow_init(&shadow, aes, |
| 240 | + info->cipher.enc ? AES_ENCRYPTION : AES_DECRYPTION); |
| 241 | + if (ret != 0) |
| 242 | + return ret; |
| 243 | + |
| 244 | + if (info->cipher.enc) |
| 245 | + ret = wc_AesCbcEncrypt(&shadow, out, in, sz); |
| 246 | +#ifdef HAVE_AES_DECRYPT |
| 247 | + else |
| 248 | + ret = wc_AesCbcDecrypt(&shadow, out, in, sz); |
| 249 | +#else |
| 250 | + else |
| 251 | + ret = CRYPTOCB_UNAVAILABLE; |
| 252 | +#endif |
| 253 | + swdev_aes_shadow_sync(aes, &shadow); |
| 254 | + wc_AesFree(&shadow); |
| 255 | + return ret; |
| 256 | +} |
| 257 | +#endif /* HAVE_AES_CBC */ |
| 258 | + |
| 259 | +#ifdef WOLFSSL_AES_COUNTER |
| 260 | +static int swdev_aes_ctr(wc_CryptoInfo* info) |
| 261 | +{ |
| 262 | + Aes* aes = info->cipher.aesctr.aes; |
| 263 | + Aes shadow; |
| 264 | + int ret; |
| 265 | + |
| 266 | + ret = swdev_aes_shadow_init(&shadow, aes, AES_ENCRYPTION); |
| 267 | + if (ret != 0) |
| 268 | + return ret; |
| 269 | + |
| 270 | + ret = wc_AesCtrEncrypt(&shadow, info->cipher.aesctr.out, |
| 271 | + info->cipher.aesctr.in, info->cipher.aesctr.sz); |
| 272 | + swdev_aes_shadow_sync(aes, &shadow); |
| 273 | + wc_AesFree(&shadow); |
| 274 | + return ret; |
| 275 | +} |
| 276 | +#endif |
| 277 | + |
| 278 | +#if defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT) |
| 279 | +static int swdev_aes_ecb(wc_CryptoInfo* info) |
| 280 | +{ |
| 281 | + Aes* aes = info->cipher.aesecb.aes; |
| 282 | + byte* out = info->cipher.aesecb.out; |
| 283 | + const byte* in = info->cipher.aesecb.in; |
| 284 | + word32 sz = info->cipher.aesecb.sz; |
| 285 | + Aes shadow; |
| 286 | + int ret; |
| 287 | + |
| 288 | + ret = swdev_aes_shadow_init(&shadow, aes, |
| 289 | + info->cipher.enc ? AES_ENCRYPTION : AES_DECRYPTION); |
| 290 | + if (ret != 0) |
| 291 | + return ret; |
| 292 | + |
| 293 | +#ifdef HAVE_AES_ECB |
| 294 | + if (info->cipher.enc) |
| 295 | + ret = wc_AesEcbEncrypt(&shadow, out, in, sz); |
| 296 | +#ifdef HAVE_AES_DECRYPT |
| 297 | + else |
| 298 | + ret = wc_AesEcbDecrypt(&shadow, out, in, sz); |
| 299 | +#else |
| 300 | + else |
| 301 | + ret = CRYPTOCB_UNAVAILABLE; |
| 302 | +#endif |
| 303 | +#elif defined(WOLFSSL_AES_DIRECT) |
| 304 | + if (sz != WC_AES_BLOCK_SIZE) { |
| 305 | + ret = CRYPTOCB_UNAVAILABLE; |
| 306 | + } |
| 307 | + else if (info->cipher.enc) { |
| 308 | + ret = wc_AesEncryptDirect(&shadow, out, in); |
| 309 | + } |
| 310 | +#ifdef HAVE_AES_DECRYPT |
| 311 | + else { |
| 312 | + ret = wc_AesDecryptDirect(&shadow, out, in); |
| 313 | + } |
| 314 | +#else |
| 315 | + else { |
| 316 | + ret = CRYPTOCB_UNAVAILABLE; |
| 317 | + } |
| 318 | +#endif |
| 319 | +#else |
| 320 | + (void)out; |
| 321 | + (void)in; |
| 322 | + (void)sz; |
| 323 | + ret = CRYPTOCB_UNAVAILABLE; |
| 324 | +#endif |
| 325 | + |
| 326 | + wc_AesFree(&shadow); |
| 327 | + return ret; |
| 328 | +} |
| 329 | +#endif /* HAVE_AES_ECB || WOLFSSL_AES_DIRECT */ |
| 330 | + |
| 331 | +#ifdef HAVE_AESGCM |
| 332 | +static int swdev_aes_gcm(wc_CryptoInfo* info) |
| 333 | +{ |
| 334 | + Aes* aes = info->cipher.enc ? info->cipher.aesgcm_enc.aes : |
| 335 | + info->cipher.aesgcm_dec.aes; |
| 336 | + Aes shadow; |
| 337 | + int ret; |
| 338 | + |
| 339 | + if (aes == NULL || aes->keylen <= 0 || aes->keylen > (int)sizeof(aes->devKey)) |
| 340 | + return BAD_FUNC_ARG; |
| 341 | + |
| 342 | + ret = wc_AesInit(&shadow, aes->heap, INVALID_DEVID); |
| 343 | + if (ret != 0) |
| 344 | + return ret; |
| 345 | + |
| 346 | + ret = wc_AesGcmSetKey(&shadow, (const byte*)aes->devKey, (word32)aes->keylen); |
| 347 | + if (ret != 0) { |
| 348 | + wc_AesFree(&shadow); |
| 349 | + return ret; |
| 350 | + } |
| 351 | + |
| 352 | + if (info->cipher.enc) { |
| 353 | + ret = wc_AesGcmEncrypt(&shadow, |
| 354 | + info->cipher.aesgcm_enc.out, info->cipher.aesgcm_enc.in, |
| 355 | + info->cipher.aesgcm_enc.sz, |
| 356 | + info->cipher.aesgcm_enc.iv, info->cipher.aesgcm_enc.ivSz, |
| 357 | + info->cipher.aesgcm_enc.authTag, |
| 358 | + info->cipher.aesgcm_enc.authTagSz, |
| 359 | + info->cipher.aesgcm_enc.authIn, |
| 360 | + info->cipher.aesgcm_enc.authInSz); |
| 361 | + } |
| 362 | + else { |
| 363 | + ret = wc_AesGcmDecrypt(&shadow, info->cipher.aesgcm_dec.out, |
| 364 | + info->cipher.aesgcm_dec.in, info->cipher.aesgcm_dec.sz, |
| 365 | + info->cipher.aesgcm_dec.iv, info->cipher.aesgcm_dec.ivSz, |
| 366 | + info->cipher.aesgcm_dec.authTag, |
| 367 | + info->cipher.aesgcm_dec.authTagSz, |
| 368 | + info->cipher.aesgcm_dec.authIn, |
| 369 | + info->cipher.aesgcm_dec.authInSz); |
| 370 | + } |
| 371 | + |
| 372 | + wc_AesFree(&shadow); |
| 373 | + return ret; |
| 374 | +} |
| 375 | +#endif /* HAVE_AESGCM */ |
| 376 | + |
| 377 | +#ifdef HAVE_AESCCM |
| 378 | +static int swdev_aes_ccm(wc_CryptoInfo* info) |
| 379 | +{ |
| 380 | + Aes* aes = info->cipher.enc ? info->cipher.aesccm_enc.aes : |
| 381 | + info->cipher.aesccm_dec.aes; |
| 382 | + Aes shadow; |
| 383 | + int ret; |
| 384 | + |
| 385 | + if (aes == NULL || aes->keylen <= 0 || aes->keylen > (int)sizeof(aes->devKey)) |
| 386 | + return BAD_FUNC_ARG; |
| 387 | + |
| 388 | + ret = wc_AesInit(&shadow, aes->heap, INVALID_DEVID); |
| 389 | + if (ret != 0) |
| 390 | + return ret; |
| 391 | + |
| 392 | + ret = wc_AesCcmSetKey(&shadow, (const byte*)aes->devKey, (word32)aes->keylen); |
| 393 | + if (ret != 0) { |
| 394 | + wc_AesFree(&shadow); |
| 395 | + return ret; |
| 396 | + } |
| 397 | + |
| 398 | + if (info->cipher.enc) { |
| 399 | + ret = wc_AesCcmEncrypt(&shadow, |
| 400 | + info->cipher.aesccm_enc.out, info->cipher.aesccm_enc.in, |
| 401 | + info->cipher.aesccm_enc.sz, |
| 402 | + info->cipher.aesccm_enc.nonce, |
| 403 | + info->cipher.aesccm_enc.nonceSz, |
| 404 | + info->cipher.aesccm_enc.authTag, |
| 405 | + info->cipher.aesccm_enc.authTagSz, |
| 406 | + info->cipher.aesccm_enc.authIn, |
| 407 | + info->cipher.aesccm_enc.authInSz); |
| 408 | + } |
| 409 | +#ifdef HAVE_AES_DECRYPT |
| 410 | + else { |
| 411 | + ret = wc_AesCcmDecrypt(&shadow, info->cipher.aesccm_dec.out, |
| 412 | + info->cipher.aesccm_dec.in, info->cipher.aesccm_dec.sz, |
| 413 | + info->cipher.aesccm_dec.nonce, |
| 414 | + info->cipher.aesccm_dec.nonceSz, |
| 415 | + info->cipher.aesccm_dec.authTag, |
| 416 | + info->cipher.aesccm_dec.authTagSz, |
| 417 | + info->cipher.aesccm_dec.authIn, |
| 418 | + info->cipher.aesccm_dec.authInSz); |
| 419 | + } |
| 420 | +#else |
| 421 | + else { |
| 422 | + ret = CRYPTOCB_UNAVAILABLE; |
| 423 | + } |
| 424 | +#endif |
| 425 | + |
| 426 | + wc_AesFree(&shadow); |
| 427 | + return ret; |
| 428 | +} |
| 429 | +#endif /* HAVE_AESCCM */ |
| 430 | +#endif /* !NO_AES */ |
| 431 | + |
182 | 432 | WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info, |
183 | 433 | void* ctx) |
184 | 434 | { |
@@ -233,6 +483,33 @@ WC_SWDEV_EXPORT int wc_SwDev_Callback(int devId, wc_CryptoInfo* info, |
233 | 483 | return CRYPTOCB_UNAVAILABLE; |
234 | 484 | } |
235 | 485 | #endif |
| 486 | +#ifndef NO_AES |
| 487 | + case WC_ALGO_TYPE_CIPHER: |
| 488 | + switch (info->cipher.type) { |
| 489 | + #ifdef HAVE_AES_CBC |
| 490 | + case WC_CIPHER_AES_CBC: |
| 491 | + return swdev_aes_cbc(info); |
| 492 | + #endif |
| 493 | + #ifdef WOLFSSL_AES_COUNTER |
| 494 | + case WC_CIPHER_AES_CTR: |
| 495 | + return swdev_aes_ctr(info); |
| 496 | + #endif |
| 497 | + #if defined(HAVE_AES_ECB) || defined(WOLFSSL_AES_DIRECT) |
| 498 | + case WC_CIPHER_AES_ECB: |
| 499 | + return swdev_aes_ecb(info); |
| 500 | + #endif |
| 501 | + #ifdef HAVE_AESGCM |
| 502 | + case WC_CIPHER_AES_GCM: |
| 503 | + return swdev_aes_gcm(info); |
| 504 | + #endif |
| 505 | + #ifdef HAVE_AESCCM |
| 506 | + case WC_CIPHER_AES_CCM: |
| 507 | + return swdev_aes_ccm(info); |
| 508 | + #endif |
| 509 | + default: |
| 510 | + return CRYPTOCB_UNAVAILABLE; |
| 511 | + } |
| 512 | +#endif /* !NO_AES */ |
236 | 513 | default: |
237 | 514 | return CRYPTOCB_UNAVAILABLE; |
238 | 515 | } |
|
0 commit comments