1use core::cell::Cell;
84
85use kernel::collections::list::{List, ListLink, ListNode};
86use kernel::debug;
87use kernel::deferred_call::{DeferredCall, DeferredCallClient};
88use kernel::hil::symmetric_encryption;
89use kernel::hil::symmetric_encryption::{
90 AES128Ctr, AES128, AES128CBC, AES128ECB, AES128_BLOCK_SIZE, AES128_KEY_SIZE, CCM_NONCE_LENGTH,
91};
92use kernel::utilities::cells::{OptionalCell, TakeCell};
93use kernel::ErrorCode;
94
95use crate::stream::SResult;
96use crate::stream::{encode_bytes, encode_u16};
97
98#[derive(Copy, Clone, Eq, PartialEq, Debug)]
99enum CCMState {
100 Idle,
101 Auth,
102 Encrypt,
103}
104
105struct CryptFunctionParameters {
107 buf: &'static mut [u8],
108 a_off: usize,
109 m_off: usize,
110 m_len: usize,
111 mic_len: usize,
112 confidential: bool,
113 encrypting: bool,
114}
115
116impl CryptFunctionParameters {
117 pub fn new(
118 buf: &'static mut [u8],
119 a_off: usize,
120 m_off: usize,
121 m_len: usize,
122 mic_len: usize,
123 confidential: bool,
124 encrypting: bool,
125 ) -> CryptFunctionParameters {
126 CryptFunctionParameters {
127 buf,
128 a_off,
129 m_off,
130 m_len,
131 mic_len,
132 confidential,
133 encrypting,
134 }
135 }
136}
137
138pub struct MuxAES128CCM<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> {
139 aes: &'a A,
140 client: OptionalCell<&'a dyn symmetric_encryption::Client<'a>>,
141 ccm_clients: List<'a, VirtualAES128CCM<'a, A>>,
142 inflight: OptionalCell<&'a VirtualAES128CCM<'a, A>>,
143 deferred_call: DeferredCall,
144}
145
146impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> MuxAES128CCM<'a, A> {
147 pub fn new(aes: &'a A) -> Self {
148 aes.enable(); Self {
150 aes,
151 client: OptionalCell::empty(),
152 ccm_clients: List::new(),
153 inflight: OptionalCell::empty(),
154 deferred_call: DeferredCall::new(),
155 }
156 }
157
158 fn do_next_op_async(&self) {
163 self.deferred_call.set();
164 }
165
166 fn do_next_op(&self) {
167 if self.inflight.is_none() {
168 let mnode = self
169 .ccm_clients
170 .iter()
171 .find(|node| node.queued_up.is_some());
172 mnode.map(|node| {
173 self.inflight.set(node);
174 let parameters: CryptFunctionParameters = node.queued_up.take().unwrap();
175 let _ = node.crypt_r(parameters).map_err(|(ecode, _)| {
177 if node.ccm_client.is_none() {
180 debug!("virtual_aes_ccm: no ccm_client is registered in VirtualAES128CCM");
181 }
182 if node.buf.is_none() {
183 debug!("virtual_aes_ccm: no buffer is binded with VirtualAES128CCM");
184 }
185 node.buf.take().map(|buf| {
187 node.ccm_client.map(move |client| {
188 client.crypt_done(buf, Err(ecode), false);
189 });
190 });
191 node.remove_from_queue();
193 self.do_next_op();
194 });
195 });
197 }
198 }
199}
200
201impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> DeferredCallClient
202 for MuxAES128CCM<'a, A>
203{
204 fn handle_deferred_call(&self) {
205 self.do_next_op();
206 }
207
208 fn register(&'static self) {
209 self.deferred_call.register(self);
210 }
211}
212
213impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> symmetric_encryption::Client<'a>
214 for MuxAES128CCM<'a, A>
215{
216 fn crypt_done(&'a self, source: Option<&'static mut [u8]>, dest: &'static mut [u8]) {
217 if self.inflight.is_none() {
218 self.client.map(move |client| {
219 client.crypt_done(source, dest);
220 });
221 return;
222 }
223 self.inflight.map(move |vaes_ccm| {
224 vaes_ccm.crypt_done(source, dest);
230 });
231 }
232}
233
234pub struct VirtualAES128CCM<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> {
235 mux: &'a MuxAES128CCM<'a, A>,
236 aes: &'a A,
237 next: ListLink<'a, VirtualAES128CCM<'a, A>>,
238
239 crypt_buf: TakeCell<'static, [u8]>,
240 crypt_auth_len: Cell<usize>,
241 crypt_enc_len: Cell<usize>,
242 ccm_client: OptionalCell<&'a dyn symmetric_encryption::CCMClient>,
243
244 state: Cell<CCMState>,
245 confidential: Cell<bool>,
246 encrypting: Cell<bool>,
247
248 buf: TakeCell<'static, [u8]>,
249 pos: Cell<(usize, usize, usize, usize)>,
250 key: Cell<[u8; AES128_KEY_SIZE]>,
251 nonce: Cell<[u8; CCM_NONCE_LENGTH]>,
252 saved_tag: Cell<[u8; AES128_BLOCK_SIZE]>,
253 queued_up: OptionalCell<CryptFunctionParameters>,
254}
255
256impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> VirtualAES128CCM<'a, A> {
257 pub fn new(
258 mux: &'a MuxAES128CCM<'a, A>,
259 crypt_buf: &'static mut [u8],
260 ) -> VirtualAES128CCM<'a, A> {
261 VirtualAES128CCM {
262 mux,
263 aes: mux.aes,
264 next: ListLink::empty(),
265 crypt_buf: TakeCell::new(crypt_buf),
266 crypt_auth_len: Cell::new(0),
267 crypt_enc_len: Cell::new(0),
268 ccm_client: OptionalCell::empty(),
269 state: Cell::new(CCMState::Idle),
270 confidential: Cell::new(false),
271 encrypting: Cell::new(false),
272 buf: TakeCell::empty(),
273 pos: Cell::new((0, 0, 0, 0)),
274 key: Cell::new(Default::default()),
275 nonce: Cell::new(Default::default()),
276 saved_tag: Cell::new(Default::default()),
277 queued_up: OptionalCell::empty(),
278 }
279 }
280
281 pub fn setup(&'a self) {
283 self.mux.ccm_clients.push_head(self);
284 }
285
286 fn prepare_ccm_buffer(
290 &self,
291 nonce: &[u8; CCM_NONCE_LENGTH],
292 mic_len: usize,
293 a_data: &[u8],
294 m_data: &[u8],
295 ) -> Result<(), ErrorCode> {
296 self.crypt_buf.map_or(Err(ErrorCode::NOMEM), |cbuf| {
297 let (auth_len, enc_len) =
298 match Self::encode_ccm_buffer(cbuf, nonce, mic_len, a_data, m_data) {
299 SResult::Done(_, out) => out,
300 SResult::Needed(_) => {
301 return Err(ErrorCode::NOMEM);
302 }
303 SResult::Error(()) => {
304 return Err(ErrorCode::FAIL);
305 }
306 };
307 self.crypt_auth_len.set(auth_len);
317 self.crypt_enc_len.set(enc_len);
318 Ok(())
319 })
320 }
321
322 fn encode_ccm_buffer(
328 buf: &mut [u8],
329 nonce: &[u8; CCM_NONCE_LENGTH],
330 mic_len: usize,
331 a_data: &[u8],
332 m_data: &[u8],
333 ) -> SResult<(usize, usize)> {
334 let mut flags: u8 = 0;
347 if a_data.len() != 0 {
348 flags |= 1 << 6;
349 }
350 if mic_len != 0 {
351 flags |= (((mic_len - 2) / 2) as u8) << 3;
352 }
353 flags |= 1;
354
355 stream_len_cond!(buf, AES128_BLOCK_SIZE);
356 buf[0] = flags;
358 buf[1..14].copy_from_slice(nonce.as_ref());
359 let mut off = enc_consume!(buf, 14; encode_u16,
360 (m_data.len() as u16).to_le());
361
362 if a_data.len() == 0 {
365 } else if a_data.len() < 0xff00_usize {
367 off = enc_consume!(buf, off; encode_u16,
369 (a_data.len() as u16).to_le());
370 } else {
371 stream_err!(());
374 }
375
376 off = enc_consume!(buf, off; encode_bytes, a_data);
378 let auth_len = off.div_ceil(AES128_BLOCK_SIZE) * AES128_BLOCK_SIZE;
379 stream_len_cond!(buf, auth_len);
380 buf[off..auth_len].iter_mut().for_each(|b| *b = 0);
381 off = auth_len;
382
383 off = enc_consume!(buf, off; encode_bytes, m_data);
385 let enc_len = off.div_ceil(AES128_BLOCK_SIZE) * AES128_BLOCK_SIZE;
386 stream_len_cond!(buf, enc_len);
387 buf[off..enc_len].iter_mut().for_each(|b| *b = 0);
388 off = enc_len;
389
390 stream_done!(off, (auth_len, enc_len));
391 }
392
393 fn reversed(&self) -> bool {
394 self.confidential.get() && !self.encrypting.get()
395 }
396
397 fn start_ccm_auth(&self) -> Result<(), ErrorCode> {
400 if !(self.state.get() == CCMState::Idle)
401 && !(self.state.get() == CCMState::Encrypt && self.reversed())
402 {
403 panic!("Called start_ccm_auth when not idle");
404 }
405
406 self.aes.set_mode_aes128cbc(true)?;
408
409 let iv = [0u8; AES128_BLOCK_SIZE];
410 let res = self.aes.set_iv(&iv);
411 if res != Ok(()) {
412 return res;
413 }
414 let res = self.aes.set_key(&self.key.get());
415 if res != Ok(()) {
416 return res;
417 }
418
419 let crypt_buf = match self.crypt_buf.take() {
420 None => panic!("Cannot perform CCM* auth because crypt_buf is not present."),
421 Some(buf) => buf,
422 };
423
424 let auth_end = if self.confidential.get() {
426 self.crypt_enc_len.get()
427 } else {
428 self.crypt_auth_len.get()
429 };
430
431 self.aes.start_message();
432 match self.aes.crypt(None, crypt_buf, 0, auth_end) {
433 None => {
434 self.state.set(CCMState::Auth);
435 Ok(())
436 }
437 Some((res, _, crypt_buf)) => {
438 self.crypt_buf.replace(crypt_buf);
440 res
441 }
442 }
443 }
444
445 fn start_ccm_encrypt(&self) -> Result<(), ErrorCode> {
446 if !(self.state.get() == CCMState::Auth)
447 && !(self.state.get() == CCMState::Idle && self.reversed())
448 {
449 return Err(ErrorCode::FAIL);
450 }
451 self.state.set(CCMState::Idle); self.aes.set_mode_aes128ctr(self.encrypting.get())?;
461
462 let res = self.aes.set_key(&self.key.get());
463 if res != Ok(()) {
464 return res;
465 }
466
467 let mut iv = [0u8; AES128_BLOCK_SIZE];
468 iv[0] = 1;
471 iv[1..1 + CCM_NONCE_LENGTH].copy_from_slice(&self.nonce.get());
472 let res = self.aes.set_iv(&iv);
473 if res != Ok(()) {
474 return res;
475 }
476
477 self.aes.start_message();
478 let crypt_buf = match self.crypt_buf.take() {
479 None => panic!("Cannot perform CCM* encrypt because crypt_buf is not present."),
480 Some(buf) => buf,
481 };
482
483 match self.aes.crypt(
484 None,
485 crypt_buf,
486 self.crypt_auth_len.get() - AES128_BLOCK_SIZE,
487 self.crypt_enc_len.get(),
488 ) {
489 None => {
490 self.state.set(CCMState::Encrypt);
491 Ok(())
492 }
493 Some((res, _, crypt_buf)) => {
494 self.crypt_buf.replace(crypt_buf);
495 res
496 }
497 }
498 }
499
500 fn end_ccm(&self) {
501 let tag_valid = self.buf.map_or(false, |buf| {
502 self.crypt_buf.map_or_else(
503 || {
504 panic!("We lost track of crypt_buf!");
505 },
506 |cbuf| {
507 let (_, m_off, m_len, mic_len) = self.pos.get();
509 let auth_len = self.crypt_auth_len.get();
510 buf[m_off..m_off + m_len].copy_from_slice(&cbuf[auth_len..auth_len + m_len]);
511
512 let m_end = m_off + m_len;
513 let tag_off = auth_len - AES128_BLOCK_SIZE;
514 if self.encrypting.get() {
515 buf[m_end..m_end + mic_len]
517 .copy_from_slice(&cbuf[tag_off..tag_off + mic_len]);
518 true
519 } else {
520 buf[m_end..m_end + mic_len]
523 .iter()
524 .zip(cbuf[tag_off..tag_off + mic_len].iter())
525 .all(|(a, b)| *a == *b)
526 }
527 },
528 )
529 });
530 self.state.set(CCMState::Idle);
532 self.remove_from_queue();
533 self.mux.do_next_op();
534 self.ccm_client.map(|client| {
535 self.buf.take().map(|buf| {
536 client.crypt_done(buf, Ok(()), tag_valid);
537 });
538 });
539 }
540
541 fn reverse_end_ccm(&self) {
542 let tag_valid = self.buf.map_or(false, |buf| {
544 self.crypt_buf.map_or_else(
545 || {
546 panic!("We lost track of crypt_buf!");
547 },
548 |cbuf| {
549 let (_, m_off, m_len, mic_len) = self.pos.get();
550
551 let tag_off = self.crypt_enc_len.get() - AES128_BLOCK_SIZE;
554 self.saved_tag.get()[..mic_len]
555 .iter()
556 .zip(cbuf[tag_off..tag_off + mic_len].iter_mut())
557 .for_each(|(a, b)| *b ^= *a);
558
559 buf[m_off + m_len..m_off + m_len + mic_len]
562 .iter()
563 .zip(cbuf[tag_off..tag_off + mic_len].iter())
564 .all(|(a, b)| *a == *b)
565 },
566 )
567 });
568 self.state.set(CCMState::Idle);
570 self.remove_from_queue();
571 self.mux.do_next_op();
572 self.ccm_client.map(|client| {
573 self.buf.take().map(|buf| {
574 client.crypt_done(buf, Ok(()), tag_valid);
575 });
576 });
577 }
578
579 fn save_tag_block(&self) {
580 let auth_len = self.crypt_auth_len.get();
583 self.crypt_buf.map(|cbuf| {
584 let mut cbuf_block = [0u8; AES128_BLOCK_SIZE];
585 cbuf_block.copy_from_slice(&cbuf[auth_len - AES128_BLOCK_SIZE..auth_len]);
586 self.saved_tag.set(cbuf_block);
587 cbuf[auth_len - AES128_BLOCK_SIZE..auth_len]
588 .iter_mut()
589 .for_each(|b| *b = 0);
590 });
591 }
592
593 fn swap_tag_block(&self) {
594 let auth_len = self.crypt_auth_len.get();
597 self.crypt_buf.map(|cbuf| {
598 let mut cbuf_block = [0u8; AES128_BLOCK_SIZE];
599 cbuf_block.copy_from_slice(&cbuf[auth_len - AES128_BLOCK_SIZE..auth_len]);
600 cbuf[auth_len - AES128_BLOCK_SIZE..auth_len].copy_from_slice(&self.saved_tag.get());
601 self.saved_tag.set(cbuf_block);
602 });
603 }
604
605 fn crypt_r(
606 &self,
607 parameter: CryptFunctionParameters,
608 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
609 let buf: &'static mut [u8] = parameter.buf;
611 let a_off: usize = parameter.a_off;
612 let m_off: usize = parameter.m_off;
613 let m_len: usize = parameter.m_len;
614 let mic_len: usize = parameter.mic_len;
615 let confidential: bool = parameter.confidential;
616 let encrypting: bool = parameter.encrypting;
617 if self.state.get() != CCMState::Idle {
619 return Err((ErrorCode::BUSY, buf));
620 }
621 if !(a_off <= m_off && m_off + m_len + mic_len <= buf.len()) {
622 return Err((ErrorCode::INVAL, buf));
623 }
624
625 self.confidential.set(confidential);
626 self.encrypting.set(encrypting);
627
628 let res = self.prepare_ccm_buffer(
629 &self.nonce.get(),
630 mic_len,
631 &buf[a_off..m_off],
632 &buf[m_off..m_off + m_len],
633 );
634 if res != Ok(()) {
635 return Err((res.unwrap_err(), buf));
636 }
637
638 let res = if !confidential || encrypting {
639 self.start_ccm_auth()
641 } else {
642 self.save_tag_block();
644 self.start_ccm_encrypt()
645 };
646
647 if res != Ok(()) {
648 Err((res.unwrap_err(), buf))
649 } else {
650 self.buf.replace(buf);
651 self.pos.set((a_off, m_off, m_len, mic_len));
652 Ok(())
653 }
654 }
655
656 fn remove_from_queue(&self) {
657 self.queued_up.clear();
658 self.mux.inflight.clear();
659 }
660}
661
662impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> symmetric_encryption::AES128CCM<'a>
663 for VirtualAES128CCM<'a, A>
664{
665 fn set_client(&self, client: &'a dyn symmetric_encryption::CCMClient) {
666 self.ccm_client.set(client);
667 }
668
669 fn set_key(&self, key: &[u8]) -> Result<(), ErrorCode> {
670 if key.len() < AES128_KEY_SIZE {
671 Err(ErrorCode::INVAL)
672 } else {
673 let mut new_key = [0u8; AES128_KEY_SIZE];
674 new_key.copy_from_slice(key);
675 self.key.set(new_key);
676 Ok(())
677 }
678 }
679
680 fn set_nonce(&self, nonce: &[u8]) -> Result<(), ErrorCode> {
681 if nonce.len() < CCM_NONCE_LENGTH {
682 Err(ErrorCode::INVAL)
683 } else {
684 let mut new_nonce = [0u8; CCM_NONCE_LENGTH];
685 new_nonce.copy_from_slice(nonce);
686 self.nonce.set(new_nonce);
687 Ok(())
688 }
689 }
690 fn crypt(
692 &self,
693 buf: &'static mut [u8],
694 a_off: usize,
695 m_off: usize,
696 m_len: usize,
697 mic_len: usize,
698 confidential: bool,
699 encrypting: bool,
700 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
701 if self.queued_up.is_some() {
702 return Err((ErrorCode::BUSY, buf));
703 }
704 if self.state.get() != CCMState::Idle {
705 return Err((ErrorCode::BUSY, buf));
706 }
707 if !(a_off <= m_off && m_off + m_len + mic_len <= buf.len()) {
708 return Err((ErrorCode::INVAL, buf));
709 }
710
711 self.queued_up.set(CryptFunctionParameters::new(
712 buf,
713 a_off,
714 m_off,
715 m_len,
716 mic_len,
717 confidential,
718 encrypting,
719 ));
720 self.mux.do_next_op_async();
721 Ok(())
722 }
723}
724
725impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> symmetric_encryption::AES128<'a>
726 for VirtualAES128CCM<'a, A>
727{
728 fn enable(&self) {
729 self.aes.enable();
730 }
731
732 fn disable(&self) {
733 self.aes.disable();
734 }
735
736 fn set_client(&'a self, client: &'a dyn symmetric_encryption::Client<'a>) {
737 self.mux.client.set(client);
738 }
739
740 fn set_key(&self, key: &[u8]) -> Result<(), ErrorCode> {
741 if self.mux.inflight.is_none() {
742 self.mux.aes.set_key(key)
743 } else {
744 Err(ErrorCode::BUSY)
745 }
746 }
747
748 fn set_iv(&self, iv: &[u8]) -> Result<(), ErrorCode> {
749 if self.mux.inflight.is_none() {
750 self.mux.aes.set_iv(iv)
751 } else {
752 Err(ErrorCode::BUSY)
753 }
754 }
755
756 fn start_message(&self) {
757 if self.mux.inflight.is_none() {
758 self.mux.aes.start_message()
759 }
760 }
761
762 fn crypt(
763 &self,
764 source: Option<&'static mut [u8]>,
765 dest: &'static mut [u8],
766 start_index: usize,
767 stop_index: usize,
768 ) -> Option<(
769 Result<(), ErrorCode>,
770 Option<&'static mut [u8]>,
771 &'static mut [u8],
772 )> {
773 if self.mux.inflight.is_none() {
774 self.mux.aes.crypt(source, dest, start_index, stop_index)
775 } else {
776 Some((Err(ErrorCode::BUSY), source, dest))
777 }
778 }
779}
780
781impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> AES128Ctr for VirtualAES128CCM<'a, A> {
782 fn set_mode_aes128ctr(&self, encrypting: bool) -> Result<(), ErrorCode> {
783 if self.mux.inflight.is_none() {
784 self.mux.aes.set_mode_aes128ctr(encrypting)
785 } else {
786 Err(ErrorCode::BUSY)
787 }
788 }
789}
790
791impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> AES128ECB for VirtualAES128CCM<'a, A> {
792 fn set_mode_aes128ecb(&self, encrypting: bool) -> Result<(), ErrorCode> {
793 if self.mux.inflight.is_none() {
794 self.mux.aes.set_mode_aes128ecb(encrypting)
795 } else {
796 Err(ErrorCode::BUSY)
797 }
798 }
799}
800
801impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> AES128CBC for VirtualAES128CCM<'a, A> {
802 fn set_mode_aes128cbc(&self, encrypting: bool) -> Result<(), ErrorCode> {
803 if self.mux.inflight.is_none() {
804 self.mux.aes.set_mode_aes128cbc(encrypting)
805 } else {
806 Err(ErrorCode::BUSY)
807 }
808 }
809}
810
811impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> symmetric_encryption::Client<'a>
812 for VirtualAES128CCM<'a, A>
813{
814 fn crypt_done(&self, _: Option<&'static mut [u8]>, crypt_buf: &'static mut [u8]) {
815 self.crypt_buf.replace(crypt_buf);
816 match self.state.get() {
817 CCMState::Idle => {}
818 CCMState::Auth => {
819 if !self.reversed() {
820 if self.confidential.get() {
821 let (_, m_off, m_len, _) = self.pos.get();
822 let auth_len = self.crypt_auth_len.get();
823 let enc_len = self.crypt_enc_len.get();
824 self.crypt_buf.map(|cbuf| {
825 let auth_last = auth_len - AES128_BLOCK_SIZE;
829 let enc_last = enc_len - AES128_BLOCK_SIZE;
830 for i in 0..AES128_BLOCK_SIZE {
831 cbuf[auth_last + i] = cbuf[enc_last + i];
832 }
833
834 self.buf.map(|buf| {
836 cbuf[auth_len..auth_len + m_len]
837 .copy_from_slice(&buf[m_off..m_off + m_len]);
838 });
839 cbuf[auth_len + m_len..enc_len]
840 .iter_mut()
841 .for_each(|b| *b = 0);
842 });
843 }
844
845 let res = self.start_ccm_encrypt();
846 if res != Ok(()) {
847 self.state.set(CCMState::Idle);
849 self.remove_from_queue();
850 self.mux.do_next_op();
851
852 self.buf.take().map(|buf| {
854 self.ccm_client.map(move |client| {
855 client.crypt_done(buf, res, false);
856 });
857 });
858 }
859 } else {
860 self.reverse_end_ccm();
861 }
862 }
863 CCMState::Encrypt => {
864 if !self.reversed() {
865 self.end_ccm();
866 } else {
867 self.swap_tag_block();
868 self.crypt_buf.map(|cbuf| {
869 let (_, m_off, m_len, _) = self.pos.get();
871 let auth_len = self.crypt_auth_len.get();
872 self.buf.map(|buf| {
873 buf[m_off..m_off + m_len]
874 .copy_from_slice(&cbuf[auth_len..auth_len + m_len]);
875 });
876
877 cbuf[self.crypt_auth_len.get() + m_len..self.crypt_enc_len.get()]
879 .iter_mut()
880 .for_each(|b| *b = 0);
881 });
882 let res = self.start_ccm_auth();
883 if res != Ok(()) {
884 self.buf.take().map(|buf| {
886 self.ccm_client.map(move |client| {
887 client.crypt_done(buf, res, false);
888 });
889 });
890 self.state.set(CCMState::Idle);
892 self.remove_from_queue();
893 self.mux.do_next_op();
894 }
895 }
896 }
897 }
898 }
899}
900
901impl<'a, A: AES128<'a> + AES128Ctr + AES128CBC + AES128ECB> ListNode<'a, VirtualAES128CCM<'a, A>>
903 for VirtualAES128CCM<'a, A>
904{
905 fn next(&'a self) -> &'a ListLink<'a, VirtualAES128CCM<'a, A>> {
906 &self.next
907 }
908}